Skip to content
Snippets Groups Projects
Select Git revision
  • d70d46fd6076171d9834f11af3a5d65ccc976289
  • master default
  • benchmark-tools
  • postgres-lambda
  • REL9_4_25
  • REL9_5_20
  • REL9_6_16
  • REL_10_11
  • REL_11_6
  • REL_12_1
  • REL_12_0
  • REL_12_RC1
  • REL_12_BETA4
  • REL9_4_24
  • REL9_5_19
  • REL9_6_15
  • REL_10_10
  • REL_11_5
  • REL_12_BETA3
  • REL9_4_23
  • REL9_5_18
  • REL9_6_14
  • REL_10_9
  • REL_11_4
24 results

sets.c

Blame
  • sets.c 4.31 KiB
    /*-------------------------------------------------------------------------
     *
     * 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)
     *
     * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
     * Portions Copyright (c) 1994, Regents of the University of California
     *
     *
     * IDENTIFICATION
     *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.32 2000/06/09 01:11:09 tgl Exp $
     *
     *-------------------------------------------------------------------------
     */
    
    #include "postgres.h"
    
    #include "access/heapam.h"
    #include "catalog/catname.h"
    #include "catalog/indexing.h"
    #include "catalog/pg_proc.h"
    #include "utils/sets.h"
    #include "utils/syscache.h"
    
    extern CommandDest whereToSendOutput;	/* defined in tcop/postgres.c */
    
    
    /*
     *	  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.
     */
    Oid
    SetDefine(char *querystr, char *typename)
    {
    	Oid			setoid;
    	char	   *procname = GENERICSETNAME;
    	char	   *fileName = "-";
    	char		realprocname[NAMEDATALEN];
    	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];
    
    	setoid = ProcedureCreate(procname,	/* changed below, after oid known */
    							 true,		/* returnsSet */
    							 typename,	/* returnTypeName */
    							 "sql",		/* languageName */
    							 querystr,	/* sourceCode */
    							 fileName,	/* fileName */
    							 true,		/* trusted */
    							 false,		/* canCache XXX appropriate? */
    							 false,		/* isStrict XXX appropriate? */
    							 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(PROCOID,
    							  ObjectIdGetDatum(setoid),
    							  0, 0, 0);
    	if (!HeapTupleIsValid(tup))
    		elog(ERROR, "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, RowExclusiveLock);
    
    		tup = SearchSysCacheTuple(PROCOID,
    								  ObjectIdGetDatum(setoid),
    								  0, 0, 0);
    		if (HeapTupleIsValid(tup))
    		{
    			newtup = heap_modifytuple(tup,
    									  procrel,
    									  replValue,
    									  replNull,
    									  repl);
    
    			heap_update(procrel, &tup->t_self, newtup, NULL);
    
    			setoid = newtup->t_data->t_oid;
    		}
    		else
    			elog(ERROR, "setin: could not find new set oid tuple");
    
    		if (RelationGetForm(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);
    		}
    		heap_close(procrel, RowExclusiveLock);
    	}
    	return setoid;
    }
    
    /* 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
     * into the :funcid.
     */
    Datum
    seteval(PG_FUNCTION_ARGS)
    {
    	Oid			funcoid = PG_GETARG_OID(0);
    
    	elog(ERROR, "seteval called for OID %u", funcoid);
    
    	PG_RETURN_INT32(0);			/* keep compiler happy */
    }