1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* sets.c
|
1997-09-07 07:04:48 +02:00
|
|
|
* Functions for sets, which are defined by queries.
|
|
|
|
* Example: a set is defined as being the result of the query
|
|
|
|
* retrieve (X.all)
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
1999-11-24 01:44:37 +01:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.28 1999/11/24 00:44:35 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
1997-01-10 21:19:49 +01:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "postgres.h"
|
1998-04-27 06:08:07 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "access/heapam.h"
|
1999-07-16 05:14:30 +02:00
|
|
|
#include "catalog/catname.h"
|
|
|
|
#include "catalog/indexing.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "catalog/pg_proc.h"
|
1999-07-16 05:14:30 +02:00
|
|
|
#include "utils/sets.h"
|
|
|
|
#include "utils/syscache.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
extern CommandDest whereToSendOutput; /* defined in tcop/postgres.c */
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
1997-09-07 07:04:48 +02:00
|
|
|
* SetDefine - converts query string defining set to an oid
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* 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.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
Oid
|
|
|
|
SetDefine(char *querystr, char *typename)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Oid setoid;
|
|
|
|
char *procname = GENERICSETNAME;
|
|
|
|
char *fileName = "-";
|
1998-07-20 18:57:18 +02:00
|
|
|
char realprocname[NAMEDATALEN];
|
1997-09-08 04:41:22 +02:00
|
|
|
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];
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
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();
|
1999-11-22 18:56:41 +01:00
|
|
|
tup = SearchSysCacheTuple(PROCOID,
|
1997-09-07 07:04:48 +02:00
|
|
|
ObjectIdGetDatum(setoid),
|
|
|
|
0, 0, 0);
|
|
|
|
if (!HeapTupleIsValid(tup))
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "setin: unable to define set %s", querystr);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 */
|
1999-09-18 21:08:25 +02:00
|
|
|
procrel = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
1998-08-19 04:04:17 +02:00
|
|
|
|
1999-11-22 18:56:41 +01:00
|
|
|
tup = SearchSysCacheTuple(PROCOID,
|
1998-09-01 06:40:42 +02:00
|
|
|
ObjectIdGetDatum(setoid),
|
|
|
|
0, 0, 0);
|
1997-09-07 07:04:48 +02:00
|
|
|
if (HeapTupleIsValid(tup))
|
|
|
|
{
|
|
|
|
newtup = heap_modifytuple(tup,
|
|
|
|
procrel,
|
|
|
|
replValue,
|
|
|
|
replNull,
|
|
|
|
repl);
|
|
|
|
|
|
|
|
setheapoverride(true);
|
1999-11-24 01:44:37 +01:00
|
|
|
heap_update(procrel, &tup->t_self, newtup, NULL);
|
1997-09-07 07:04:48 +02:00
|
|
|
setheapoverride(false);
|
|
|
|
|
1998-11-27 20:52:36 +01:00
|
|
|
setoid = newtup->t_data->t_oid;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
else
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "setin: could not find new set oid tuple");
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
if (RelationGetForm(procrel)->relhasindex)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Relation idescs[Num_pg_proc_indices];
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
CatalogOpenIndices(Num_pg_proc_indices, Name_pg_proc_indices, idescs);
|
|
|
|
CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup);
|
|
|
|
CatalogCloseIndices(Num_pg_proc_indices, idescs);
|
|
|
|
}
|
1999-09-18 21:08:25 +02:00
|
|
|
heap_close(procrel, RowExclusiveLock);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
return setoid;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/* This function is a placeholder. The parser uses the OID of this
|
1996-07-09 08:22:35 +02:00
|
|
|
* function to fill in the :funcid field of a set. This routine is
|
1997-09-07 07:04:48 +02:00
|
|
|
* never executed. At runtime, the OID of the actual set is substituted
|
1996-07-09 08:22:35 +02:00
|
|
|
* into the :funcid.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
seteval(Oid funcoid)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
return 17;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|