Index: openacs-4/packages/acs-tcl/tcl/00-database-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/00-database-procs.tcl,v diff -u -N -r1.69 -r1.70 --- openacs-4/packages/acs-tcl/tcl/00-database-procs.tcl 16 Jul 2007 00:54:16 -0000 1.69 +++ openacs-4/packages/acs-tcl/tcl/00-database-procs.tcl 17 Sep 2007 09:43:55 -0000 1.70 @@ -360,23 +360,56 @@ switch $driverkey { postgresql { - # the following query will return a nextval if the sequnce - # is of relkind = 'S' (a sequnce). if it is not of relkind = 'S' - # we will try querying it as a view: +# # the following query will return a nextval if the sequnce +# # is of relkind = 'S' (a sequnce). if it is not of relkind = 'S' +# # we will try querying it as a view: - if { [db_0or1row -dbn $dbn nextval_sequence " - select nextval('${sequence}') as nextval - where (select relkind - from pg_class - where relname = '${sequence}') = 'S' - "]} { - return $nextval - } else { - ns_log debug "db_nextval: sequence($sequence) is not a real sequence. perhaps it uses the view hack." - db_0or1row -dbn $dbn nextval_view "select nextval from ${sequence}" - return $nextval +# if { [db_0or1row -dbn $dbn nextval_sequence " +# select nextval('${sequence}') as nextval +# where (select relkind +# from pg_class +# where relname = '${sequence}') = 'S' +# "]} { +# return $nextval +# } else { +# ns_log debug "db_nextval: sequence($sequence) is not a real sequence. perhaps it uses the view hack." +# db_0or1row -dbn $dbn nextval_view "select nextval from ${sequence}" +# return $nextval +# } + # + # The code above is just for documentation, how it worked + # before the change below. We keep now a per-thread table of + # the "known" sequences to avoid at runtime the query, + # whether the specified sequence is a real sequence or a + # view. This change makes this function more than a factor + # of 2 faster than before. + # + # Disadvantage: If a new sequence is created, it is not immediately + # picked up (restart the server, or terminate thread). + # + # The best solution would certainly be to fix all views on sequences + # and to call db_nextval only with real sequence names. + # + # - gustaf neumann (17.9.2007) + # + if {![info exists ::db::sequences]} { + ns_log notice "-- creating per thread sequence table" + namespace eval ::db {} + foreach s [db_list -dbn $dbn relnames "select relname, relkind from pg_class where relkind = 'S'"] { + set ::db::sequences($s) 1 } - + } + if {[info exists ::db::sequences(t_$sequence)]} { + #ns_log notice "-- found t_$sequence" + set nextval [db_string -dbn $dbn "nextval" "select nextval('t_$sequence')"] + } elseif {[info exists ::db::sequences($sequence)]} { + #ns_log notice "-- found $sequence" + set nextval [db_string -dbn $dbn "nextval" "select nextval('$sequence')"] + } else { + #ns_log notice "-- use view" + set nextval [db_string -dbn $dbn "nextval" "select nextval from $sequence"] + } + return $nextval } oracle -