[HACKERS] Last minute mini-proposal (I know, I know) for PQexecf()

2007-03-30 Thread korryd
While cleaning up some pg_migrator code
(http://pgfoundry.org/projects/pg-migrator/) it occurred to me that a
typical libpq client application spends a lot of code constructing SQL
commands.  The code typically looks like this:

a) allocate enough room to hold the command 
b) sprintf( command, text, argument, argument, argument, ... )
c) PQexec( conn, command )
d) free( command )

In most cases, the amount of memory that you allocate in step a) is just
an educated guess.  It's typically more room than you need,
occassionally less room than you need (and you get a buffer overflow
exploit), and it's rarely maintained properly when you modify the
command text (or the argument list).

I'd like to see a new variant on PQexec():

PGresult * PQexecf(PGconn *conn, const char *fmt, ...);

PQexecf() simply performs steps a, b, c, and d for you. And you call it
like this:

PQexecf( conn, text, argument, argument, argument, ... )

PQexecf() is just a wrapper around the already existing
createPQExpBuffer(), enlargePQExpBuffer(), printfPQExpBuffer(), and
PQexec() so it introduces no new code (other than assembling the
wrapper) and doesn't change any existing code.  PQexecf() is similar to
PQexecParams() but it much simpler to use (and should be very familiar
to C programmers).  PQexecf() is not intended as a replacement for
PQprepare() and PQexecPrepared() - you should use prepare/exec when you
want to execute a command many times.

I could eliminate a lot of client-side code if PQexecf() were available
- and the code that I could remove is the code that's most likely to be
buggy and least likely to be properly maintained.

I've thrown together an UNTESTED prototype (below), just to get the idea
across - you'll recognize that most of this code is identical to
printPQExpBuffer().  In the prototype, I'm keeping a static PQExpBuffer
that grows to the hold the largest string ever required by the client
application - that part seems to be a point for discussion, but since
the detail is hidden in the implementation, we could adjust the code
later if necessary (without changing the interface).

Of course, I could include an implementation of PQexecf() in each of my
client applications if it were not available in libpq, but that would be
silly and I'd have to invent my own createPQExpBuffer() /
enlargePQExpBuffer() code since those functions are not an official part
of libpq (and won't even be available to a Win32 client application).

Is it just too late to even think about this for 8.3? (Bruce laughed at
me when I suggested the idea :-)  

   -- Korry
  [EMAIL PROTECTED]
  http://www.enterprisedb.com



PGresult *
PQexecf(PGconn *conn, const char *fmt, ...)
{
static PQExpBuffer str;
va_listargs;

if (str == NULL)
str = createPQExpBuffer();

for (;;)
{
/*
 * Try to format the given string into the available space; but 
if
 * there's hardly any space, don't bother trying, just fall 
through to
 * enlarge the buffer first.
 */
if (str-maxlen  str-len + 16)
{
size_t avail = str-maxlen - str-len - 1;
intnprinted;

va_start(args, fmt);
nprinted = vsnprintf(str-data + str-len, avail, fmt, 
args);
va_end(args);

/*
 * Note: some versions of vsnprintf return the number 
of chars
 * actually stored, but at least one returns -1 on 
failure. Be
 * conservative about believing whether the print 
worked.
 */
if (nprinted = 0  nprinted  (int) avail - 1)
{
/* Success.  Note nprinted does not include 
trailing null. */
str-len += nprinted;
break;
}
}
/* Double the buffer size and try again. */
if (!enlargePQExpBuffer(str, str-maxlen))
return PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR); /* 
oops, out of
memory */
}

return PQexec(conn, str-data);
}



Re: [HACKERS] Last minute mini-proposal (I know, I know) forPQexecf()

2007-03-31 Thread korryd
 Way too late for 8.3 --- if we were going to do something like this,
 we should think first and program later.  In particular, blindly
 adopting the sprintf format string definition doesn't seem very helpful.
 The sorts of escapes I'd want to have are properly quoted SQL
 identifier, properly quoted SQL literal, etc.  A large fraction of
 what sprintf knows about is more or less irrelevant to the task of
 creating SQL commands.
 
 Also, how does this interact with parameterized or prepared commands?
 If we wanted PQexecf we'd soon want PQexecParamsf, etc.  I don't think
 we really want so much duplicate logic there --- it'd be better to
 decouple the string-building functionality from the query-sending
 functionality.  Probably better to consider something like
 PQformatQuery() that passes back a malloc'd string.


I agree with almost everything that you said.  I really like the idea of
new format specifiers for properly quoted stuff.

I like the idea of adding a new PQformatQuery() function. And once you
have PQformatQuery(), you can easily change the implementation of
PQexecf() without affecting any client applications. I'm not sure that
we would need a PQexecParamsf(), but I'm willing to accept that we might
(it seems more likely that we would want PQpreparef()).

But we would want those features in addition to PQexecf(), not instead
of PQexecf().

PQexecf() would be useful today, even without all of those extras - just
look at the the source code for pg_dump to see how much code we would
eliminate with a simple PQexecf().

There are two reasons I threw out this idea now.

1) I didn't think of it until a few days ago...

2) It's important to get the interface into a near-future release so
that client applications can start using it soon.  We can add features
and refactor the implementation later.  I assume that my prototype is
not horrible (it's based on existing code).

-- Korry


--
  Korry Douglas[EMAIL PROTECTED]
  EnterpriseDB  http://www.enterprisedb.com


Re: [HACKERS] Last minute mini-proposal (I know, I know)forPQexecf()

2007-03-31 Thread korryd
 It's important to get the *right* interface into the first release
 that has it.  


Agreed, that's why I proposed the right interface to begin with :-)


 The day before feature freeze is way too late for
 blue-sky design IMHO.


Ok, I can certainly bring this up again in the next release cycle.  And
I can include my own private implementation in any client applications
until we have something similar in libpq.


 I note that the nominal schedule
 http://www.postgresql.org/developer/roadmap
 says that all major proposals should have been made and reviewed at
 least a month ago.  


Consider me spanked... (and quit giggling Bruce).

-- Korry



--
  Korry Douglas[EMAIL PROTECTED]
  EnterpriseDB  http://www.enterprisedb.com


Re: [HACKERS] Last minute mini-proposal (I know, Iknow)forPQexecf()

2007-03-31 Thread korryd
 [EMAIL PROTECTED] wrote:
   I note that the nominal schedule
   http://www.postgresql.org/developer/roadmap
   says that all major proposals should have been made and reviewed at
   least a month ago.  
  
  
  Consider me spanked... (and quit giggling Bruce).
 
 Awe, you got me.  :-)
 
 FYI, I sung Dream On to Korry when he first suggested this to me:


I tried to forget the singing...  it was your evil laughter that still
haunts my dreams.

-- Korry


Re: [HACKERS] Last minute mini-proposal (I know, Iknow)forPQexecf()

2007-04-01 Thread korryd
 I don't necessarily object to PQexecf() as a shortcut for some
 multi-step operation, but I don't think you've got the format string
 semantics down yet.


I'm thinking that we could start with the standard conversion
specifiers - those are well understood and would be expected by just
about any C developer.

In particular, the %d, %u, %e, and %f format specifiers are immediately
useful.

If we start with the standard set, you can start to use PQexecf()
immediately and we could promise to maintain *at least* that set.

We can add more specifiers (for proper quoting and such) later - we
can't break existing client applications if we just add to the set of
supported specifiers; the function gets more useful as time goes by.


-- Korry


Re: [HACKERS] Last minute mini-proposal (I know, Iknow)forPQexecf()

2007-04-01 Thread korryd
 That's exactly the approach I don't want to take.  To implement our
 quoting-escape additions, we'll have to stop relying on sprintf and
 implement for ourselves whatever standard C escapes we want to
 support.  


Ok - then it seems like it might make sense to implement PQexecf() in
terms of src/port/snprintf.c (and enhance that family of functions to
support the quoting conversion specifiers that we want).

Let's just pick up this discussion in the next release cycle.

Bruce - can you add a TODO for this topic?  Thanks.


-- Korry


--
  Korry Douglas[EMAIL PROTECTED]
  EnterpriseDB  http://www.enterprisedb.com


Re: [HACKERS] EXPLAIN/EXPLAIN ANALYSE for pl/pgsql functions

2007-04-23 Thread korryd
  How much effort would it be to add EXPLAIN/EXPLAIN ANALYSE capability to
  pl/pgsql functions?
  
  what I mean, is either a special mode, where SELECT my_plpgsql_func()
  would print all query plans instead or in addition to executing them, or
  some way for EXPLAIN to pass some flags to functions so that they can
  do the right thing.
 
 I agree this is an important thing to have.


This is a feature I would like to add to the elusive PL/pgSQL
debugger/tracer/profiler.


-- Korry


[HACKERS] [Fwd: pg_migrator: in-place upgrade tool at pgFoundry]

2006-11-01 Thread korryd





EnterpriseDB has created a new project at pgFoundry - http://pgfoundry.org/projects/pg-migrator/

pg_migrator is a tool that can in-place upgrade existing data without the usual dump/reload cycle.

The pg_migrator project site (at pgFoundry) contains a complete implementation of the functionality described below as well as a copy of the introductory document that I've included in this message.

We would welcome feedback on implementation details and ideas for improvements. 

 -- Korry






--
 Korry Douglas [EMAIL PROTECTED]
 EnterpriseDB http://www.enterprisedb.com




=

--
PG_MIGRATOR: IN-PLACE UPGRADES FOR POSTGRESQL 
--

Upgrading a PostgreSQL database from one release to another can be an
expensive process. For minor upgrades, you can simply install new executables
and forget about upgrading existing data. But for major upgrades, you have to
export all of your data (using pg_dump), install the new release, run initdb
to create a new cluster, and then import your old data. If you have a lot of
data, that can take a considerable amount of time (hours?, days?). If you have
too much data, you may have to buy more storage since you need enough room to
hold the original data plus the exported data.

EnterpriseDB is contributing a new tool, pg_migrator, that can reduce the
amount of time (and disk space) required for many upgrades.

--
WHAT IT DOES
--

PG_migrator is a tool (not a complete solution) that performs an in-place
upgrade of existing data. For many upgrades, the data stored in user-defined
tables does not have to change when moving from one version of PostgreSQL to
another. Some upgrades require changes in the on-disk representation of data;
pg_migrator cannot help in those upgrades. However, many upgrades require no
changes to the on-disk representation of a user-defined table and, in those
cases, pg_migrator will move existing user-defined tables from the old
database cluster into the new cluster.

There are two factors that determine whether an in-place upgrade is practical.

Every table in a cluster (actually, every table created by a given version)
shares the same infrastructure layout. By infrastructure, we mean the on-disk
representation of the table headers and trailers and the on-disk
representation of tuple headers. If the infrastructure changes between the old
version of PostgreSQL and the new version, pg_migrator cannot move existing
tables to the new cluster (you'll have to pg_dump the old data and then import
that data into the new cluster).

Occasionally, a PostgreSQL release introduces a change to the on-disk
representation of a data type. For example, PostgreSQL version 8.2 changes the
layout for values of type INET and CIDR. If you are not storing any values of
type INET (or CIDR), pg_migrator can upgrade any table in your cluster. If you
are storing values of type INET (or CIDR) in some tables, you must
export/import those tables, but pg_migrator can in-place upgrade other tables
(a change in infrastructure means that you have to export/import every table).

If a new version of PostgreSQL does not change the infrastructure layout and
does not change the on-disk representation of a data type (that you are
using), you can pg_migrator to save a tremendous amount of time (and disk
space).

--
HOW IT WORKS
--

To use pg_migrator during an upgrade, you start by installing a fresh cluster
(using the newest version) in a new directory. When you've finished installing
the new version, the new cluster will contain the new executables (postmaster,
pg_dump, ...) and the usual template0, template1, and postgresql databases,
but no user-defined tables. At this point, you can shutdown the new postmaster
(we presume that you shutdown the old postmaster prior to creating the new
cluster) and invoke pg_migrator.

When pg_migrator starts, it runs through a verification process that ensures
that all required executables (the old postmaster, the new postmaster,
pg_dump, pg_resetxlog, ...) are present and contain the expected version
numbers. The verification process also checks the old and new $PGDATA
directories to ensure that the expected files and subdirectories (base,
global, pg_clog, pg_xlog, ...) are in place.  If the verification process
succeeds, pg_migrator starts the old postmaster and runs pg_dumpall
--schema-only to capture the metadata contained in the old cluster. The script
produced by pg_dumpall will be used in a later step to 

[HACKERS] Coding style question

2006-11-02 Thread korryd




I've noticed a trend in the PostgreSQL code base - for some reason, we tend to avoid initializing automatic variables (actually, the code base is pretty mixed on this point).

For example in _bt_check_unique() we have:




static TransactionId
_bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
 Buffer buf, ScanKey itup_scankey)
{
 TupleDesc itupdesc = RelationGetDescr(rel);
 int natts = rel-rd_rel-relnatts;
 OffsetNumber offset,
 maxoff;
 Page page;
 BTPageOpaque opaque;
 Buffer nbuf = InvalidBuffer;

 page = BufferGetPage(buf);
 opaque = (BTPageOpaque) PageGetSpecialPointer(page);
 maxoff = PageGetMaxOffsetNumber(page);
 offset = _bt_binsrch(rel, buf, natts, itup_scankey, false);
	...






Notice that four variables are not initialized; instead we assign values to them immediately after declaring them. 

I would probably write that as:




static TransactionId
_bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
 Buffer buf, ScanKey itup_scankey)
{
 TupleDesc itupdesc = RelationGetDescr(rel);
 int natts = rel-rd_rel-relnatts;
 Page page = BufferGetPage(buf);
 OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
 BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page);
 OffsetNumber offset = _bt_binsrch(rel, buf, natts, itup_scankey, false);
 Buffer nbuf = InvalidBuffer;
	...





I'm not trying to be pedantic (it just comes naturally), but is there some reason that the first form would be better? I know that there is no difference in the resulting code, so this is purely a style/maintainability question.

I guess the first form let's you intersperse comments (which is good). 

On the other hand, the second form makes it easy to see which variables are un-initialized. The second form also prevents you from adding any code between declaring the variable and assigning a value to it (which is good in complicated code; you might introduce a reference to an unitialized variable).

Just curious.

 -- Korry




Re: [HACKERS] Coding style question

2006-11-02 Thread korryd







The disadvantage of using initializers is that you end up contorting the code
to allow you to squeeze things into the initializers and it limits what you
can do later to the code without undoing them.

For example, if later you find out you have to, say, lock a table before the
itupdesc initializer then all of the sudden you have to rip out all the
initializers and rewrite them as assignments after the statement acquiring the
table lock.



Good point (and I can't argue with your example). But, I think initializers also force you to declare variables in the scope where they are needed. Instead of declaring every variable at the start of the function, it's better to declare them as nested as practical (not as nested as possible, but as nested as practical). That means, you might write the code like this:


static TransactionId
_bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
 Buffer buf, ScanKey itup_scankey)
{ 
 if( lockTable( ... ))
 {
 TupleDesc itupdesc = RelationGetDescr(rel);
 int natts = rel-rd_rel-relnatts;
 Page page = BufferGetPage(buf);
 OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
 ...


The biggest advantage to that style of coding is that you know when each variable goes out of scope. If you declare every variable at the start of the function (and you don't initialize it), it can be very difficult to tell at which points in the code the variable holds a (meaningful) value. If you declare local variables in nested scopes, you know that the variable disappears as soon as you see the closing '}'.



I admit to a certain affinity to lisp-style programming and that does lead to
me tending to try to use initializers doing lots of work in expressions. But I
find I usually end up undoing them before I'm finished because I need to
include a statement or because too much work needs to be done with one
variable before some other variable can be initialized.

But including complex expensive function calls in initializers will probably
only confuse people trying to follow the logic of the code. Including
_bt_binsrch() as an initializer for example hides the bulk of the work this
function does.

People expect initializers to be simple expressions, macro calls, accessor
functions, and so on. Not to call out to complex functions that implement key
bits of the function behaviour.



Agreed - you can certainly take initialization way too far, I just think we don't take it far enough in many cases and I'm wondering if there's some advantage that I'm not aware of.

 -- Korry





Re: [HACKERS] Coding style question

2006-11-02 Thread korryd






 Shouldn't we turn on warnings by the compiler on uninitialized
 variables? This can also be helpful.

Those warnings should already be enabled, at least with GCC.



Yes, the compiler can detect unitialized variables, 

But, that introduces a new problem. There are a lot of tools out there (like GCC) that can find unitialized variables (or more specifically, variables which are used before initialization). I've seen too many less-scarred developers add an  = NULL to quiet down the tool. But that's (arguably) worse than leaving the variable uninitialized - if you simply initialize a variable to a known (but not correct) value, you've disabled the tool; it can't help you find improperly initialized variables anymore. The variable has a value, but you still don't know at which point in time it has a correct value.

That's another reason I prefer initializers (and nested variable declarations) - I can put off creating the variable until I can assign a meaningful value to it. (I don't go so far as to introduce artificial scopes just for the sake of nesting variable declarations).

Too many scars...

 -- Korry





Re: [HACKERS] Coding style question

2006-11-02 Thread korryd







Yeah, I agree with that.  But as Andrew noted, we don't really have any
hard and fast coding rules --- the only guideline is to do your best to
make your code readable, because other people *will* have to read it.



I'm not really looking for hard/fast rules. Just picking brains. 



In the particular example here I find Korry's proposed coding less
readable than what's there, but I can't entirely put my finger on why.
Maybe it's just the knowledge that it's less easily modifiable.  In general,
I'd say initializers with side effects or nonobvious ordering dependencies
are definitely bad style, because someone might innocently rearrange
them, eg to group all the variables of the same datatype together.
You can get away with ordering dependencies like

TupleDescitupdesc = RelationGetDescr(rel);
int  natts = itupdesc-natts;

because the dependency is obvious (even to the compiler).  Anything more
complex than this, I'd write as a statement not an initializer.



Agreed - I contrived an example (I just happened to be reading _bt_check_unique()). In fact, I would not initialize 'offset' as I suggested, but I probably would initialize just about everything else.

(In fact, in the actual code, there's a code-comment that describes the initialization of offset - I would certainly leave that in place).

 -- Korry






Re: [HACKERS] Coding style question

2006-11-02 Thread korryd






[EMAIL PROTECTED] writes:
 initializers also force you to declare variables in the scope where they
 are needed.  Instead of declaring every variable at the start of the
 function, it's better to declare them as nested as practical (not as
 nested as possible, but as nested as practical).

I agree that in many places it'd be better style to declare variables in
smaller scopes ... but that's not the point you started the thread with.
In any case, the initializer-vs-assignment decision is the same no
matter what scope you're talking about --- I don't see how that forces
you to do it either way.



Right - I should have said that proper initialization encourages you to declare variables in nested scopes (proper meaning that the initializer puts a meaningful value into the variable, not just a default NULL or 0) - if the initializer depends on a computed value, you can't initialize until that value has been computed. 

I guess the two issues are not all that related - you can initialize without nesting (in many cases) and you can nest without initializing. They are both readability and maintainability issues to me.

Thanks for the feedback. 

 -- Korry






Re: [HACKERS] Coding style question

2006-11-02 Thread korryd







Well, clearly you should only assign meaningful values to variables, but
I don't see anything wrong with omitting an initializer, initializing
the variable before using it, and letting the compiler warn you if you
forget to do this correctly. 



The problem that that introduces is that you have to unravel the code if you want to maintain it, especially if you're changing complex code (many code paths) and some variable is initialized long after it's declared. You have to search the code to figure out at which point the variable gains a meaningful value. In the example I cited, each variable was assigned a value immediately after being declared. That wasn't a good example - in some places, we declare all variables at the start of the function, but we don't assign a value to some of the variables until 20 or 30 lines of code later (and if there are multiple code paths, you have to follow each one to find out when the variable gains a meaningful value). 



I agree with Greg's rationale on when to
include an initializer in a variable declaration (when the initializer
is trivial: e.g. casting a void * to a more specific pointer type, or
using one of the PG_GETARG_XXX() macros in a UDF).



I agree too. I wasn't trying to suggest that every variable must be initialized. 

I think Tom stated it pretty well:

When the variable is going to be set anyway in straight-line code at the top of the function, then it's mostly a matter of taste whether you set it with an initializer or an assignment.

the key phrase is: set anyway in straigh-tline code at the top of the function


 (I don't go so far as to introduce artificial scopes just for the sake
 of nesting variable declarations).

I don't introduce artificial scopes either. However, I do try to declare
variables in the most-tightly-enclosing scope. For example, if a
variable is only used in one branch of an if statement, declare the
variable inside that block, not in the enclosing scope.


good...


I also find that if you're declaring a lot of variables in a single
block, that's usually a sign that the block is too large and should be
refactored (e.g. by moving some code into separate functions). If you
keep your functions manageably small (which is not always the case in
the Postgres code, unfortunately), the declarations are usually pretty
clearly visible.



I couldn't agree more.

Thanks for your comments.

 -- Korry





[HACKERS] Scanner/Parser question - what does _P imply?

2007-01-18 Thread korryd
I can't find an authoritative answer to this question.

Many of the keywords listed in keywords.c are defined with symbolic
names that end in '_P' (underscore P).

What differentiates those keywords from the other keywords?  What does
the 'P' stand for?

Are those PostgreSQL-specific keywords (i.e. keywords not defined by the
SQL standard)?

Thanks.


   -- Korry


--
  Korry Douglas[EMAIL PROTECTED]
  EnterpriseDB  http://www.enterprisedb.com


Re: [HACKERS] Scanner/Parser question - what does _P imply?

2007-01-18 Thread korryd
 P = Parser.  The reason for the _P is just to avoid conflicts with
 other definitions of the macro name, either in our own code or various
 platforms' header files.  We haven't been totally consistent about it,
 but roughly speaking we've stuck _P on when it was either known or
 seemed likely that there might be a conflict.
 
 Some years ago there was discussion of consistently P-ifying *all* those
 macros, but it didn't get done; I think Thomas or somebody objected that
 it would make gram.y needlessly harder to read.


Ahhh... now it's clear. 

Thanks.


-- Korry


Re: [HACKERS] 10 weeks to feature freeze (Pending Work)

2007-01-22 Thread korryd


 Thought I would do a poll of what is happening in the world for 8.3. I have:
 
 Alvaro Herrera: Autovacuum improvements (maintenance window etc..)
 Gavin Sherry: Bitmap Indexes (on disk), possible basic Window functions
 Jonah Harris: WITH/Recursive Queries?
 Andrei Kovalesvki: Some Win32 work with Magnus
 Magnus Hagander: VC++ support (thank goodness)
 Heikki Linnakangas: Working on Vacuum for Bitmap Indexes?
 Oleg Bartunov: Tsearch2 in core
 Neil Conway: Patch Review (including enums), pg_fcache



Korry Douglas: PL/pgSQL debugger (and probably a PL/pgSQL execution profiler as 
well)




--
  Korry Douglas[EMAIL PROTECTED]
  EnterpriseDB  http://www.enterprisedb.com


Re: [HACKERS] Scanner/Parser question - what does _P imply?

2007-01-25 Thread korryd
  Some years ago there was discussion of consistently P-ifying *all* those
  macros, but it didn't get done; I think Thomas or somebody objected that
  it would make gram.y needlessly harder to read.
 
 Are there many people who read gram.y on a regular base?


I can't seem to put it down :-)

From the back cover:

A rollercoaster ride of passion, heart-stopping adventures, and
gut-wrenching laughs ... every bit as thrilling as copyfuncs.c,
more of a tearjerker than bufmgr.c, and as deliciously naughty
as MySQL's item.cc.  


Get gram.y, in stores now (or order at Amazon.com, delivered in a plain
brown wrapper).


-- Korry


[HACKERS] shared_preload_libraries support on Win32?

2007-01-29 Thread korryd
(working on the PL debugger...) 

It appears that the libraries listed in shared_preload_libraries will
*not* be inherited by spawned backends on Win32 platforms.

Do we have to do something special to make that work?

Using ProcessExplorer (from sysinternals.com), I can see that my plugins
are loaded into the postmaster, but not into the individual backends.

If I set local_preload_libraries equal to shared_preload_libraries, the
plugins are loaded into the backends as expected (so it seems unlikely
that I have a pathname or permissions problem).

Should we just call process_shared_preload_libraries() after calling
read_nondefault_variables() (in SubPostmasterMain())?

-- Korry


--
  Korry Douglas[EMAIL PROTECTED]
  EnterpriseDB  http://www.enterprisedb.com


Re: [HACKERS] shared_preload_libraries support on Win32?

2007-01-29 Thread korryd
 Actually ... I take that back.  I was thinking of the original purpose
 of preload_libraries, which was strictly performance optimization.
 But in the new world of plugins there may be functional reasons for
 wanting libraries to be loaded into backends --- and
 shared_preload_libraries is not isomorphic to local_preload_libraries.
 The permissions situation is different.


And, shared_preload_libraries is processed (in the postmaster) before
the shared-memory segment is created, so a shared_preload_library can
call RequestAddinShmemSpace() and RequestAddinLWLocks(), but a
local_preload_library cannot.


-- Korry


Re: [HACKERS] shared_preload_libraries support on Win32?

2007-01-29 Thread korryd
  And, shared_preload_libraries is processed (in the postmaster) before
  the shared-memory segment is created, so a shared_preload_library can
  call RequestAddinShmemSpace() and RequestAddinLWLocks(), but a
  local_preload_library cannot.
 
 That doesn't seem like an issue though, since the copy in the postmaster
 will have done that anyway.


You're right - we need the copy in the postmaster (to setup shared
memory and LW locks), and we need them in the backends too.  I just want
to avoid having to set both shared_preload_libraries and
local_preload_libraries (to the same thing).  Adding a call to
process_shared_preload_libraries() in SubPostmasterMain() seems to fix
the problem for me.

Thanks for your input.  I'll submit a patch.


-- Korry


Re: [HACKERS] shared_preload_libraries support on Win32?

2007-01-29 Thread korryd
  You're right - we need the copy in the postmaster (to setup shared
  memory and LW locks), and we need them in the backends too.
 
  Just make sure you don't load the libraries in bgwriter et al ...
 
 I see that Korry's patch doesn't do that, but I'm wondering why exactly.
 In a Unix environment such libraries *would* be propagated into bgwriter
 and every other postmaster child; is there a reason for the setup on
 Windows to be different?  In particular, what about autovacuum, which
 ISTM should be as close to a standard backend as possible?

I thought about that too...  does autovacuum ever need to re-index?  If
so, it seems that it would need access to any index functions (for
function-based indexes) that might reside in a shared_preload_library.


 Either way we do it, authors of plugins used this way will have to test
 both cases (I'm glad I insisted on EXEC_BACKEND mode being testable under
 Unix ...)


And I'm glad that RequestAddinShmemSpace() and RequestAddinLWLocks()
don't complain if called after postmaster start :-)

-- Korry


--
  Korry Douglas[EMAIL PROTECTED]
  EnterpriseDB  http://www.enterprisedb.com


Re: [HACKERS] [GENERAL] 8.2.1 Compiling Error

2007-01-31 Thread korryd
On Wed, 2007-01-31 at 11:38 -0800, elein wrote:

 - Forwarded message from elein [EMAIL PROTECTED] -
 
 To: pgsql-general@postgresql.org
 Cc: elein [EMAIL PROTECTED]
 Subject: [GENERAL] 8.2.1 Compiling Error
 Mail-Followup-To: pgsql-general@postgresql.org
 From: elein [EMAIL PROTECTED]
 
 
 Debian Linux. Have always built from scratch with no problem.
 
 This is 8.2.1 from postgresql.org.
 
 Conf line is:
 --prefix=/local/pgsql82 --enable-depend --enable-cassert --enable-debug 
 --with-tcl --with-python --with-perl  --with-pgport=5432



Don't know if it will help, but you might take a peek at
http://archives.postgresql.org/pgsql-ports/2006-09/msg5.php

-- Korry



Re: [HACKERS] Logging functions executed by queries in 8.2?

2007-02-06 Thread korryd
 Josh Berkus josh@agliodbs.com writes:
  In recent versions, we've changed the logging of function executions so 
  that only the function call is logged, and not any of the queries which it 
  may execute internally.  While most of the time this method is superior 
  for performance analysis, in applications with extensive multi-line stored 
  procedures sometimes you want to log each individual query.
 
 ISTM that the wave of the future for this is an instrumentation plug-in,
 not further kluging of the query logging functionality.  I had the
 impression that Korry and EDB had some prototype capability in that
 direction already, and surely it shouldn't be that hard to write if not.


There's a sort of proof-of-concept PL/pgSQL tracer plugin in the
debugger project on pgFoundry - I haven't played with it in a few months
so I can't promise that it will run at the moment.

If anyone is interested, let me know and I'll add this to my ToDo
list.  

-- Korry


Re: [HACKERS] Logging functions executed by queries in 8.2?

2007-02-07 Thread korryd
  If anyone is interested, let me know and I'll add this to my ToDo
  list.
 
 The Sun benchmarking team needs this.  However, we need to be able to feed 
 the data into some kind of mass analysis ala pg_fouine so that we can do 
 overall performance analysis.


I've also included a PL/pgSQL profiler in the PL debugger project - this
plugin spits out an XML profile so you should be able to massage
it/aggregate it however you like.

-- Korry



Re: [HACKERS] [PATCHES]

2007-02-28 Thread korryd
  Not that I think that anyone owning both a law degree and a computer
  in 2007 should legitimately be able to plead innocence here.  FAST
  Australia's lawyers are making themselves look like idiots, and the
  same for every other company tacking on such notices.  I think the
  real bottom line here is we don't accept patches from idiots.
 
 I think we don't accept patches from idiots is a bit harsh.


I agree, after all, you've accepted some of my patches and... oh,
wait...


-- Korry