
--	Function: delete_location.sql
--      note that this deletes entries from some tables that do not
--      have foreign keys that mandate deletion, but that have location
--      data that should be deleted as part of a delete location function
--

CREATE OR REPLACE FUNCTION delete_location (varchar(8))
RETURNS INT  AS '
        DECLARE postlid ALIAS FOR $1;
                iret_code INT;
BEGIN
  	--
  	-- Delete Hgstation records
        -- Hgstation has fk referencing RiverStat
  	--
        DELETE FROM  Hgstation       WHERE lid = postlid;

  	--
  	-- Delete riverstation records
  	--
  	iret_code := delete_riverstat(postlid);

        --
        -- Delete reservoir related entries
        --
	iret_code :=delete_resvr(postlid);

	--
        -- Delete qc related records
        --
        DELETE FROM  IngestFilter    WHERE lid = postlid;
 	DELETE FROM  LocDataLimits   WHERE lid = postlid;
	DELETE FROM  RejectedData    WHERE lid = postlid;
	DELETE FROM  AlertAlarmVal   WHERE lid = postlid;
	DELETE FROM  AdjustFactor    WHERE lid = postlid;

	--
	-- Delete location related entries
	--
        DELETE FROM  Contacts        WHERE lid = postlid;
        DELETE FROM  Dcp             WHERE lid = postlid;
        DELETE FROM  Observer        WHERE lid = postlid;
        DELETE FROM  Telem           WHERE lid = postlid;
 
	DELETE FROM  ContingencyValue WHERE lid = postlid;
        DELETE FROM  FcstDischarge   WHERE lid = postlid;
        DELETE FROM  FcstHeight      WHERE lid = postlid;
        DELETE FROM  FcstPrecip      WHERE lid = postlid;
        DELETE FROM  FcstTemperature WHERE lid = postlid;
        DELETE FROM  FcstOther       WHERE lid = postlid;
 	DELETE FROM  ProcValue       WHERE lid = postlid;
 	DELETE FROM  CommentValue    WHERE lid = postlid;
  	DELETE FROM  PairedValue     WHERE lid = postlid;
	DELETE FROM  UnkStnValue     WHERE lid = postlid;
 	DELETE FROM  UnkStn          WHERE lid = postlid;

        DELETE FROM  LatestObsValue  WHERE lid = postlid;
        DELETE FROM  RiverStatus     WHERE lid = postlid;

        DELETE FROM  Agricultural    WHERE lid = postlid;
        DELETE FROM  Discharge       WHERE lid = postlid;
        DELETE FROM  Evaporation     WHERE lid = postlid;
        DELETE FROM  FishCount       WHERE lid = postlid;
        DELETE FROM  FloodTs         WHERE lid = postlid;
	DELETE FROM  GateDam         WHERE lid = postlid;
        DELETE FROM  Ground          WHERE lid = postlid;
        DELETE FROM  Height          WHERE lid = postlid;
	DELETE FROM  Ice             WHERE lid = postlid;
        DELETE FROM  Lake            WHERE lid = postlid;
        DELETE FROM  Moisture        WHERE lid = postlid;
        DELETE FROM  Power           WHERE lid = postlid;
	DELETE FROM  Pressure        WHERE lid = postlid;
	DELETE FROM  Radiation       WHERE lid = postlid;
        DELETE FROM  Snow            WHERE lid = postlid;
        DELETE FROM  Temperature     WHERE lid = postlid;
        DELETE FROM  WaterQuality    WHERE lid = postlid;
        DELETE FROM  Weather         WHERE lid = postlid;
        DELETE FROM  Wind            WHERE lid = postlid;
        DELETE FROM  YUnique         WHERE lid = postlid;
 
        DELETE FROM  ArealFcst       WHERE lid = postlid;
        DELETE FROM  ArealObs        WHERE lid = postlid;

        DELETE FROM  MonthlyValues   WHERE lid = postlid;

        DELETE FROM  CurPC           WHERE lid = postlid;
        DELETE FROM  CurPP           WHERE lid = postlid; 
        DELETE FROM  HourlyPC        WHERE lid = postlid;
        DELETE FROM  HourlyPP        WHERE lid = postlid;
        DELETE FROM  RawPC           WHERE lid = postlid;
        DELETE FROM  RawPP           WHERE lid = postlid;
        DELETE FROM  RawPother       WHERE lid = postlid;

        DELETE FROM  LocExtAgency    WHERE lid = postlid;
	DELETE FROM  LocImage        WHERE lid = postlid;
        DELETE FROM  OFSStnTrans     WHERE lid = postlid;
	DELETE FROM  ProductLink     WHERE lid = postlid;
 
 	DELETE FROM  StnClass 	     WHERE lid = postlid;

        DELETE FROM  Location        WHERE lid = postlid;
 
RETURN 0;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------
--
--	proc_delete_radar.sql
--	Supports a cascading delete when
--	a row is removed from the RadarLoc table.
--

CREATE OR REPLACE FUNCTION delete_radar (char(3)) RETURNS INT  AS '
DECLARE delradid ALIAS FOR $1;
BEGIN
	DELETE FROM   DpaAdapt		  WHERE radid = delradid;
	DELETE FROM   RWRadarResult       WHERE radid = delradid;
	DELETE FROM   RWBiasDyn           WHERE radid = delradid;
	DELETE FROM   DPARadar            WHERE radid = delradid;
	DELETE FROM   RadarLoc            WHERE radid = delradid;
RETURN 0;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------
--
--	delete_resvr.sql
--	Supports a cascading delete when
--	a row is removed from the reservoir table.
--

CREATE OR REPLACE FUNCTION delete_resvr (varchar(8))
RETURNS INT  AS '
DECLARE postlid ALIAS FOR $1;
BEGIN
	DELETE FROM rescap    WHERE lid = postlid;
	DELETE FROM reservoir WHERE lid = postlid;
RETURN 0;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------

--	delete_riverstat.sql
--	Supports a cascading delete when
--	a row is removed from the riverstat table.
--

CREATE OR REPLACE FUNCTION delete_riverstat (varchar(8))
RETURNS INT  AS '
DECLARE postlid ALIAS FOR $1;
BEGIN
        -- 
        -- Delete riverstation related records
        -- 
        DELETE FROM  Benchmark    WHERE lid = postlid; 
        DELETE FROM  Countynum    WHERE lid = postlid; 
        DELETE FROM  Crest        WHERE lid = postlid; 
        DELETE FROM  Datum        WHERE lid = postlid; 
        DELETE FROM  Descrip      WHERE lid = postlid; 
	DELETE FROM  Flood        WHERE lid = postlid; 
        DELETE FROM  Floodcat     WHERE lid = postlid; 
        DELETE FROM  Floodstmt    WHERE lid = postlid; 
        DELETE FROM  FpPrevProd   WHERE lid = postlid; 
        DELETE FROM  Gage         WHERE lid = postlid; 
        DELETE FROM  Lowwater     WHERE lid = postlid; 
        DELETE FROM  Pub          WHERE lid = postlid; 
        DELETE FROM  Rating       WHERE lid = postlid; 
        DELETE FROM  RatingShift  WHERE lid = postlid; 
        DELETE FROM  Refer        WHERE lid = postlid; 
        DELETE FROM  RpfFcstPoint WHERE lid = postlid;
        DELETE FROM  SSHPConfig   WHERE lid = postlid;
        DELETE FROM  UnitGraph    WHERE lid = postlid;
	DELETE FROM  Zonenum      WHERE lid = postlid; 
        DELETE FROM  Riverstat    WHERE lid = postlid; 
RETURN 0;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------
--
--     fcst_pe()
--     Post the data to the appropriate pe-based table.
--     Modified for postgresql Sep 28, 2004
--

CREATE OR REPLACE FUNCTION fcst_pe
	(
         varchar(8),
         varchar(2),
	 integer,
	 varchar(2),
	 varchar(1),
	 float4,
         timestamp,
         timestamp,	
         float8,
         varchar(1),
         integer,
         integer,
         varchar(10),
         timestamp,
         timestamp,
         integer
	)
	
RETURNS INT  AS '
        DECLARE fcst_record     fcstheight%ROWTYPE;
		newlid          ALIAS FOR   $1;	
		newpe           ALIAS FOR   $2;
		newdur          ALIAS FOR   $3;
		newts           ALIAS FOR   $4;
		newextr         ALIAS FOR   $5;
		newprob         ALIAS FOR   $6;
		newvalidtime    ALIAS FOR   $7;
		newbasistime    ALIAS FOR   $8;
		newvalue        ALIAS FOR   $9;
		newrawqual      ALIAS FOR   $10;
		newqc           ALIAS FOR   $11;
		newrev	        ALIAS FOR   $12;
		newprid         ALIAS FOR   $13;
		newprodtime     ALIAS FOR   $14;
		newposttime     ALIAS FOR   $15;
		do_update       ALIAS FOR   $16;
                conf_update     integer;

BEGIN
    conf_update := 0;
------------------------------------------------------
--Post forecast height data
--
  if newpe like ''H%'' then
     SELECT INTO fcst_record * FROM FcstHeight
     WHERE lid = newlid
     AND   pe = newpe
     AND   dur = newdur
     AND   ts = newts
     AND   extremum = newextr
     AND   probability  = newprob
     AND   basistime = newbasistime
     AND   validtime = newvalidtime;

     if FOUND then
        if fcst_record.value = -9999. then
           conf_update := 1;
        else
           if do_update = 2 then
              if fcst_record.value <> newvalue then
                 conf_update := 1;
              end if;
           else
              if do_update = 1 then
                 conf_update := 1;
              end if;
           end if;
        end if;
        
        if conf_update = 1 then
           UPDATE FcstHeight SET
	   value          = newvalue,
	   shef_qual_code = newrawqual,
	   quality_code   = newqc,
	   revision       = newrev,
	   product_id     = newprid,
	   producttime    = newprodtime,
	   postingtime    = newposttime
	   WHERE lid = newlid and pe  = newpe and
	   dur = newdur and ts  = newts and
	   extremum     = newextr and
	   probability  = newprob and
	   validtime    = newvalidtime and
	   basistime    = newbasistime;
        end if;
     else
	INSERT INTO FcstHeight
	VALUES(newlid, newpe, newdur, newts, newextr, newprob, newvalidtime,
        newbasistime, newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
        newposttime);				
     end if;

--
--Process forecast precip data
--
  elsif newpe like ''P%'' then
        SELECT INTO fcst_record * FROM FcstPrecip 
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   probability  = newprob
        AND   basistime = newbasistime
        AND   validtime = newvalidtime;

        if FOUND then
           if fcst_record.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if fcst_record.value <> newvalue then 
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE FcstPrecip SET 
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe  = newpe and
              dur = newdur and ts  = newts and
              extremum     = newextr and
              probability  = newprob and
              validtime    = newvalidtime and
              basistime    = newbasistime;
           end if;
        else
           INSERT INTO FcstPrecip
           VALUES( newlid, newpe, newdur, newts, newextr, newprob, newvalidtime,
           newbasistime,newvalue, newrawqual, newqc, newrev,newprid,newprodtime,
           newposttime);
        end if;

--
--Process forecast discharge data
--
  elsif newpe like ''Q%'' then
        SELECT INTO fcst_record * FROM FcstDischarge
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   probability  = newprob
        AND   basistime = newbasistime
        AND   validtime = newvalidtime;

        if FOUND then
           if fcst_record.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if fcst_record.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;
           
           if conf_update = 1 then
              UPDATE FcstDischarge SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe  = newpe and
              dur = newdur and ts  = newts and
              extremum     = newextr and
              probability  = newprob and
              validtime    = newvalidtime and
              basistime    = newbasistime;
           end if;
        else
           INSERT INTO FcstDischarge
           VALUES( newlid, newpe, newdur, newts, newextr, newprob, newvalidtime,
           newbasistime,newvalue,newrawqual, newqc, newrev, newprid,newprodtime,
           newposttime);
        end if;

--
--Process forecast temperature amounts
--
  elsif newpe like ''T%'' then
        SELECT INTO fcst_record * FROM FcstTemperature
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   probability  = newprob
        AND   basistime = newbasistime
        AND   validtime = newvalidtime;

        if FOUND then
           if fcst_record.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if fcst_record.value <> newvalue then 
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE FcstTemperature SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe  = newpe and
              dur = newdur and ts  = newts and
              extremum     = newextr and
              probability  = newprob and
              validtime    = newvalidtime and
              basistime    = newbasistime;
           end if;
        else
           INSERT INTO FcstTemperature
           VALUES( newlid, newpe, newdur, newts, newextr, newprob, newvalidtime,
           newbasistime,newvalue,newrawqual,newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process forecast other data    
--
  else         
       SELECT INTO fcst_record * FROM FcstOther
       WHERE lid = newlid
       AND   pe = newpe
       AND   dur = newdur
       AND   ts = newts
       AND   extremum = newextr
       AND   probability  = newprob
       AND   basistime = newbasistime
       AND   validtime = newvalidtime;

       if FOUND then
          if fcst_record.value = -9999. then
             conf_update := 1;
          else
             if do_update = 2 then
                if fcst_record.value <> newvalue then 
                   conf_update := 1;
                end if;
             else
                if do_update = 1 then
                   conf_update := 1;
                end if;
             end if;
          end if;

          if conf_update = 1 then
             UPDATE FcstOther SET
             value          = newvalue,
             shef_qual_code = newrawqual,
             quality_code   = newqc,
             revision       = newrev,
             product_id     = newprid,
             producttime    = newprodtime,
             postingtime    = newposttime
             WHERE lid = newlid and pe  = newpe and
             dur = newdur and ts  = newts and
             extremum     = newextr and
             probability  = newprob and
             validtime    = newvalidtime and
             basistime    = newbasistime;
          end if;
       else
          INSERT INTO FcstOther
          VALUES( newlid, newpe, newdur, newts, newextr, newprob, newvalidtime,
          newbasistime,newvalue,newrawqual,newqc, newrev, newprid, newprodtime,
          newposttime);
       end if;
  end if;

RETURN NULL;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------
--
--	Function: load_obs_river.sql
--      Purpose:  Loads the latest valid observed data record for the
-- 	specified key into the RiverStatus table.
--      Modified for postgresql: Sep 27, 2004
--

CREATE OR REPLACE FUNCTION load_obs_river
	(
	 varchar(8),
	 varchar(2),
	 varchar(2)
	)
RETURNS INT     AS '
	--
	-- Local variables
	--
        DECLARE rstat        riverstatus%ROWTYPE;
                postlid      ALIAS FOR  $1;
                postpe       ALIAS FOR  $2;
                postts       ALIAS FOR  $3;

	        curdur       int;
	        curextr      char(1);
	        curtime	     timestamp;
	        curvalue     float = -9999.;
	        qc_threshold int = 1073741824;
                rstat_found  boolean;
BEGIN
	-- Determine if record already exists
        SELECT INTO rstat * FROM riverstatus
	WHERE lid = postlid and pe = postpe and ts = postts;
		
        rstat_found := FOUND;
		
	-- Get the latest valid value from the appropriate table
	-- note that for all the queries, only data that is instantaneous
	-- and having a null extremum is considered.  this constraint results
	-- from the fact that we are trying to find the latest obstime for 
	-- a given lid, pe, ts but the tables being read also have dur and 
	-- extremum as key fields.  this approach is considered ok since
	-- observed data is rarely ever of anything but null extremum and
	-- instantaneous duration.  a more robust alternative that uses the
	-- maximum value, regardless of duration or extremum, for the 
	-- latest time was considered, but not implemented since this
	-- would add more processing time just to consider a case
	-- that would very rarely, if ever, occur.
	
	if postpe like ''Q%'' then
	   SELECT INTO curtime max(obstime)
                FROM discharge
		WHERE lid = postlid and pe = postpe and ts = postts and 
		dur = 0 and extremum = ''Z'' and quality_code >= qc_threshold;	
	   SELECT INTO curdur, curextr, curvalue 
                dur, extremum, "value"
	   	FROM discharge
		WHERE lid = postlid and pe = postpe and ts = postts and
		dur = 0 and extremum = ''Z'' and quality_code >= qc_threshold and
		obstime = curtime;
        elsif postpe like ''H%'' then
	   SELECT INTO curtime max(obstime)
                FROM height
		WHERE lid = postlid and pe = postpe and ts = postts and 
		dur = 0 and extremum = ''Z'' and quality_code >= qc_threshold;
	   SELECT INTO curdur, curextr, curvalue
                dur, extremum, "value"
                FROM height
		WHERE lid = postlid and pe = postpe and ts = postts and 
		dur = 0 and extremum = ''Z'' and quality_code >= qc_threshold and
		obstime = curtime;
	end if;
			 
	-- If no value found, then delete any record that may be
	-- in the riverstatus table, which can occur when 
	-- this function is called by an application deleting the
	-- last item for the lid,pe,ts combination
	
	if rstat_found = FALSE AND curvalue IS NULL then
		RETURN 0;
	elsif rstat_found AND curvalue IS NULL then
	        DELETE FROM riverstatus
                   WHERE lid = postlid and pe = postpe and ts = postts;
	
	-- If entry exists already, then update it
	-- on updates, dont bother resetting basistime and probability
        elsif rstat_found then
                UPDATE riverstatus
                  SET   dur        = curdur,
		  	extremum   = curextr,
		        validtime  = curtime,
                        "value"      = curvalue
                  WHERE lid = postlid and pe = postpe and ts = postts;

	-- Insert new entry
	-- set probability to default and basistime to NULL
        else
                INSERT INTO RiverStatus
                VALUES
                (
                        postlid,   postpe,    curdur,
			postts,    curextr,   -1.,  
			curtime,   NULL,      curvalue
                );
        end if;
RETURN 0;
END;
'  LANGUAGE 'plpgsql';
-------------------------------------------------------------------------------
--
--	Procedure:	obs_pe.sql
-- 	Main procedure for posting to pe-based tables.
--      updated for PostgreSQL June  2004
--      Called by post_pe_data routine 
-- 

CREATE OR REPLACE FUNCTION obs_pe (
         varchar(8),
         varchar(2),
         integer,
         varchar(2),
         varchar(1),
         timestamp,            
         float8,
         varchar(1),
         integer,
         integer,
         varchar(10),
         timestamp,
         timestamp,
         integer
         )
RETURNS INT     AS '
DECLARE obs_rec       height%ROWTYPE;
        newlid        ALIAS FOR   $1;
        newpe         ALIAS FOR   $2;
        newdur        ALIAS FOR   $3;
        newts         ALIAS FOR   $4;
        newextr       ALIAS FOR   $5;
        newobstime    ALIAS FOR   $6;
        newvalue      ALIAS FOR   $7;
        newrawqual    ALIAS FOR   $8;
        newqc         ALIAS FOR   $9;
        newrev        ALIAS FOR   $10;
        newprid       ALIAS FOR   $11;
        newprodtime   ALIAS FOR   $12;
        newposttime   ALIAS FOR   $13;
        do_update     ALIAS FOR   $14;
        conf_update   integer;
BEGIN
    conf_update := 0;
------------------------------------------------------
-- Process the data based on the PE attribute
-- The more common PE are placed earliest in this if-elseif stack
-- The order is height (H), pressure (Pspecial), precip (Pother),
-- discharge (Q), snow (S), temperature (T), wind (U), then...
-- agricultural (A), evaporation (E), fishcount(F), ground (G),
-- ice (I), lake (L), moisture (M), gatedam (N), radiation (R),
-- power (V), waterquality (W), weather (X), yunique (Y).
------------------------------------------------------
--
--Process height data
--
  if newpe like ''H%'' then				

     SELECT INTO obs_rec * FROM height
     WHERE lid = newlid
     AND   pe = newpe
     AND   dur = newdur
     AND   ts = newts
     AND   extremum = newextr
     AND   obstime = newobstime;

     if FOUND then
        if obs_rec.value = -9999. then
           conf_update := 1;
        else
           if do_update = 2 then
              if obs_rec.value <> newvalue then
                 conf_update := 1;
              end if;
           else 
              if do_update = 1 then
                 conf_update := 1;
              end if;
           end if;
        end if;

        if conf_update = 1 then
           UPDATE height SET
           value          = newvalue,
           shef_qual_code = newrawqual,
           quality_code   = newqc,
           revision       = newrev,
           product_id     = newprid,
           producttime    = newprodtime,
           postingtime    = newposttime
           WHERE lid = newlid and pe = newpe and
           dur = newdur and ts = newts and
           extremum = newextr and obstime = newobstime;
         end if;

    else
       INSERT INTO height
       VALUES ( newlid, newpe, newdur, newts, newextr, newobstime, 
       newvalue, newrawqual, newqc, newrev, newprid, newprodtime, 
       newposttime);
    end if;
		   
--
--Process pressure data
--
  elsif newpe in (''PA'', ''PD'', ''PE'', ''PL'') then
        SELECT INTO obs_rec * FROM pressure
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else 
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE pressure SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
       else
           INSERT INTO pressure
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime, 
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime, 
           newposttime);
       end if;

--
--Process Discharge data
--
  elsif newpe like ''Q%'' then                
        SELECT INTO obs_rec * FROM discharge
	WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE discharge SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
       else
           INSERT INTO discharge
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
       end if;

--
--Process snow data
--
  elsif newpe like ''S%'' then
   
        SELECT INTO obs_rec * FROM snow
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE snow SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
       else
           INSERT INTO snow
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
       end if;
	
--
--Process temperature data
--
  elsif newpe like ''T%'' then                
   
        SELECT INTO obs_rec * FROM temperature
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1  then
              UPDATE temperature SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO temperature
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;
   
 --
 --Process wind data
 --
   elsif newpe like ''U%'' then                
   
        SELECT INTO obs_rec * FROM wind
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE wind SET
              value      = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO wind
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;
	
--
--Process agricultural data
--

  elsif newpe like ''A%'' then                
   
        SELECT INTO obs_rec * FROM agricultural
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE agricultural SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO agricultural
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;
   
 --
 --Process evaporation data
 --
   elsif newpe like ''E%'' then
   
         SELECT INTO obs_rec * FROM evaporation
         WHERE lid = newlid
         AND   pe = newpe
         AND   dur = newdur
         AND   ts = newts
         AND   extremum = newextr
         AND   obstime = newobstime;

         if FOUND then
            if obs_rec.value = -9999. then
               conf_update := 1;
            else
               if do_update = 2 then
                  if obs_rec.value <> newvalue then
                     conf_update := 1;
                  end if;
               else
                  if do_update = 1 then
                     conf_update := 1;
                  end if;
               end if;
            end if;

            if conf_update = 1 then
               UPDATE evaporation SET
               value          = newvalue,
               shef_qual_code = newrawqual,
               quality_code   = newqc,
               revision       = newrev,
               product_id     = newprid,
               producttime    = newprodtime,
               postingtime    = newposttime
               WHERE lid = newlid and pe = newpe and
               dur = newdur and ts = newts and
               extremum = newextr and obstime = newobstime;
            end if;
         else
            INSERT INTO evaporation
            VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
            newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
            newposttime);
         end if;

--
--Process fish count data
--
  elsif newpe like ''F%'' then
   
        SELECT INTO obs_rec * FROM fishcount
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE fishcount SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO fishcount
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process ground data
--
  elsif newpe like ''G%'' then                
   
        SELECT INTO obs_rec * FROM ground
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE ground SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO ground
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process Ice data
--
  elsif newpe like ''I%'' then                               
   
        SELECT INTO obs_rec * FROM ice
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE ice SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO ice
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;
		      
--
--Process lake data
--
  elsif newpe like ''L%'' then                                
   
        SELECT INTO obs_rec * FROM lake
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE lake SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO lake
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process moisture data
--
  elsif newpe like ''M%'' then
   
        SELECT INTO obs_rec * FROM moisture
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE moisture SET
              value      = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
          end if; 
        else
           INSERT INTO moisture
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process gate and dam data
--
  elsif newpe like ''N%'' then
   
        SELECT INTO obs_rec * FROM gatedam
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE gatedam SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if; 
        else
           INSERT INTO gatedam
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process radiation data
--
  elsif newpe like ''R%'' then                                
   
        SELECT INTO obs_rec * FROM radiation
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                  if do_update = 1 then
                     conf_update := 1;
                  end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE radiation SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO radiation
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process generation and generator data
--
  elsif newpe like ''V%'' then                
   
        SELECT INTO obs_rec * FROM power
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE power SET
              value      = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if; 
        else
           INSERT INTO power
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process water quality data
--
  elsif newpe like ''W%'' then		      
   
        SELECT INTO obs_rec * FROM waterquality
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE waterquality SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO waterquality
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process weather data
--
  elsif newpe like ''X%'' then		      
   
        SELECT INTO obs_rec * FROM weather
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE weather SET
              value      = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO weather
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

--
--Process Yunique data
--
  elsif newpe like ''Y%'' then                
   
        SELECT INTO obs_rec * FROM yunique
        WHERE lid = newlid
        AND   pe = newpe
        AND   dur = newdur
        AND   ts = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE yunique SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO yunique
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime,
           newvalue, newrawqual, newqc, newrev, newprid, newprodtime,
           newposttime);
        end if;

  end if;

RETURN 0;
END;
'  LANGUAGE 'plpgsql';
-------------------------------------------------------------------------------
--
--	Function:	obs_precip.sql
-- 	Main procedure for posting precip data to pe-based tables.
--      Modified for postgresql Sep 28, 2004
-- 

CREATE OR REPLACE FUNCTION obs_precip
	(
	 varchar(8),
	 varchar(2),
	 integer,
	 varchar(2),
         varchar(1),
         timestamp,
         float8,
         varchar(1),
         integer,
         integer,
         varchar(10),
         timestamp,
         timestamp,
         integer
	)
RETURNS INT     AS '
        DECLARE obs_precip_rec rawpp%ROWTYPE;
                newlid         ALIAS FOR   $1;
                newpe          ALIAS FOR   $2;
                newdur         ALIAS FOR   $3;
                newts          ALIAS FOR   $4;
                newextr        ALIAS FOR   $5;
                newobstime     ALIAS FOR   $6;
                newvalue       ALIAS FOR   $7;
                newrawqual     ALIAS FOR   $8;
                newqc          ALIAS FOR   $9;
                newrev         ALIAS FOR   $10;
                newprid        ALIAS FOR   $11;
                newprodtime    ALIAS FOR   $12;
                newposttime    ALIAS FOR   $13;
                do_update      ALIAS FOR   $14;
                conf_update    integer;

BEGIN
    conf_update := 0;

--Process the data based on the PE attribute
--Post data to the appropriate table as instructed
--      
	
--
--Post PC data
--
  if (newpe = ''PC'') then				
      SELECT INTO obs_precip_rec * FROM rawPC 
      WHERE lid = newlid
      AND   pe  = newpe
      AND   dur = newdur
      AND   ts  = newts
      AND   extremum = newextr
      AND   obstime = newobstime;

      if FOUND then
         if obs_precip_rec.value = -9999. then
            conf_update := 1;
         else
            if do_update = 2 then
               if obs_precip_rec.value <> newvalue then 
                  conf_update := 1;
               end if;
            else
               if do_update = 1 then
                  conf_update := 1;
               end if;
            end if;
         end if;

         if conf_update = 1 then
            UPDATE rawPC SET
	    value          = newvalue,
	    shef_qual_code = newrawqual,
	    quality_code   = newqc, 
	    revision       = newrev,
	    product_id     = newprid,
	    producttime    = newprodtime,
	    postingtime    = newposttime
	    WHERE lid = newlid and pe = newpe and
	    dur = newdur and ts = newts and
	    extremum = newextr and obstime = newobstime;
	 end if;

      else
         INSERT INTO rawPC
         VALUES ( newlid, newpe, newdur, newts, newextr, newobstime, newvalue, 
         newrawqual, newqc, newrev, newprid, newprodtime, newposttime);
      end if;

-- 
--Post PP data  
--
  elsif (newpe = ''PP'') then				
        SELECT INTO obs_precip_rec * FROM rawPP 
        WHERE lid = newlid
        AND   pe  = newpe
        AND   dur = newdur
        AND   ts  = newts
        AND   extremum = newextr
        AND   obstime = newobstime;

        if FOUND then
           if obs_precip_rec.value = -9999. then
              conf_update := 1;
           else
              if do_update = 2 then
                 if obs_precip_rec.value <> newvalue then
                    conf_update := 1;
                 end if;
              else
                 if do_update = 1 then
                    conf_update := 1;
                 end if;
              end if;
           end if;

           if conf_update = 1 then
              UPDATE rawPP SET
              value          = newvalue,
              shef_qual_code = newrawqual,
              quality_code   = newqc,
              revision       = newrev,
              product_id     = newprid,
              producttime    = newprodtime,
              postingtime    = newposttime
              WHERE lid = newlid and pe = newpe and
              dur = newdur and ts = newts and
              extremum = newextr and obstime = newobstime;
           end if;
        else
           INSERT INTO rawPP
           VALUES ( newlid, newpe, newdur, newts, newextr, newobstime, newvalue,
           newrawqual, newqc, newrev, newprid, newprodtime, newposttime);
        end if;

-- 
--Post precip data that is neither PC nor PP
--    
  else				
     SELECT INTO obs_precip_rec * FROM rawPother
     WHERE lid = newlid
     AND   pe  = newpe
     AND   dur = newdur
     AND   ts  = newts
     AND   extremum = newextr
     AND   obstime = newobstime;

     if FOUND then
        if obs_precip_rec.value = -9999. then
           conf_update := 1;
        else
           if do_update = 2 then
              if obs_precip_rec.value <> newvalue then
                 conf_update := 1;
              end if;
           else
              if do_update = 1 then
                 conf_update := 1;
              end if;
           end if;
        end if;

        if conf_update = 1 then
           UPDATE rawPother SET
           value          = newvalue,
           shef_qual_code = newrawqual,
           quality_code   = newqc,
           revision       = newrev,
           product_id     = newprid,
           producttime    = newprodtime,
           postingtime    = newposttime
           WHERE lid = newlid and pe = newpe and
           dur = newdur and ts = newts and
           extremum = newextr and obstime = newobstime;
        end if;

      else
        INSERT INTO rawPother
        VALUES ( newlid, newpe, newdur, newts, newextr, newobstime, newvalue,
        newrawqual, newqc, newrev, newprid, newprodtime, newposttime);
      end if;
  end if;
	   
RETURN 0;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION obs_rawpc_ins () RETURNS TRIGGER AS '
BEGIN
    INSERT INTO CurPC
    VALUES (
            NEW.lid,
            NEW.pe,
            NEW.dur,
            NEW.ts,
            NEW.extremum,
            NEW.obstime,
            NEW.value,
            NEW.shef_qual_code,
            NEW.quality_code,
            NEW.revision,
            NEW.product_id,
            NEW.producttime,
            NEW.postingtime
           );
RETURN NEW;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION obs_rawpc_upd () RETURNS TRIGGER AS '
DECLARE counter int;
BEGIN
    --Update the info in CurPC
      SELECT INTO counter count(*) FROM CurPC
      WHERE   lid      = NEW.lid
      and     pe       = NEW.pe
      and     dur      = NEW.dur
      and     ts       = NEW.ts
      and     extremum = NEW.extremum
      and     obstime  = NEW.obstime;

      if (counter > 0) then
          UPDATE CurPC
          SET   value          = NEW.value,
          shef_qual_code = NEW.shef_qual_code,
          quality_code   = NEW.quality_code,
          revision       = NEW.revision,
          product_id     = NEW.product_id,
          producttime    = NEW.producttime,
          postingtime    = NEW.postingtime
          WHERE lid      = NEW.lid
          and pe       = NEW.pe
          and dur      = NEW.dur
          and ts       = NEW.ts
          and extremum = NEW.extremum
          and obstime  = NEW.obstime;
      else
          INSERT INTO CurPC
          VALUES ( NEW.lid, NEW.pe, NEW.dur, NEW.ts, NEW.extremum, NEW.obstime,
          NEW.value, NEW.shef_qual_code, NEW.quality_code, NEW.revision,
          NEW.product_id, NEW.producttime, NEW.postingtime);

          DELETE FROM CurPC
          WHERE lid      = OLD.lid
          AND   pe       = OLD.pe
          AND   dur      = OLD.dur
          AND   ts       = OLD.ts
          AND   extremum = OLD.extremum
          AND   obstime  = OLD.obstime;
      end if;

RETURN NEW;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION obs_rawpp_ins () RETURNS TRIGGER AS '
BEGIN
    INSERT INTO CurPP
    VALUES ( NEW.lid, NEW.pe, NEW.dur, NEW.ts, NEW.extremum, NEW.obstime,
    NEW.value, NEW.shef_qual_code, NEW.quality_code, NEW.revision, 
    NEW.product_id, NEW.producttime, NEW.postingtime);
RETURN NEW;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION obs_rawpp_upd () RETURNS TRIGGER AS '
DECLARE counter int;
BEGIN
    --Update the info in CurPP
    SELECT INTO counter count(*) FROM CurPP
    WHERE   lid      = NEW.lid
    and     pe       = NEW.pe
    and     dur      = NEW.dur
    and     ts       = NEW.ts
    and     extremum = NEW.extremum
    and     obstime  = NEW.obstime;

    if (counter > 0) then
       UPDATE CurPP
       SET   value          = NEW.value,
       shef_qual_code = NEW.shef_qual_code,
       quality_code   = NEW.quality_code,
       revision       = NEW.revision,
       product_id     = NEW.product_id,
       producttime    = NEW.producttime,
       postingtime    = NEW.postingtime
       WHERE lid      = NEW.lid
       and pe         = NEW.pe
       and dur        = NEW.dur
       and ts         = NEW.ts
       and extremum   = NEW.extremum
       and obstime    = NEW.obstime;
    else
       INSERT INTO CurPP
       VALUES ( NEW.lid, NEW.pe, NEW.dur, NEW.ts, NEW.extremum, NEW.obstime,
       NEW.value, NEW.shef_qual_code, NEW.quality_code, NEW.revision,
       NEW.product_id, NEW.producttime, NEW.postingtime);

       DELETE FROM CurPP
       WHERE lid      = OLD.lid
       AND   pe       = OLD.pe
       AND   dur      = OLD.dur
       AND   ts       = OLD.ts
       AND   extremum = OLD.extremum
       AND   obstime  = OLD.obstime;
    end if;

RETURN NEW;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION obs_river_ins () RETURNS TRIGGER AS '
DECLARE river RiverStatus%ROWTYPE;
BEGIN
    --
    -- dont insert data that is definitely bad note the hardcoded number.
	
    if (NEW.quality_code < 1073741824) then
        RETURN NEW;
    end if;
	 
    SELECT INTO river * FROM RiverStatus
    WHERE lid = NEW.lid
    AND   pe = NEW.pe
    AND   ts = NEW.ts;

    if FOUND then
	-- need to check for NULL obstime or the logical check will fail
	-- if updating, dont bother with null probability or basistime fields
		 	
	UPDATE RiverStatus 
	SET   dur = NEW.dur,
	extremum  = NEW.extremum,
	validtime = NEW.obstime,
	value     = NEW.value		
	WHERE lid = NEW.lid and pe = NEW.pe
	and ts = NEW.ts and (validtime < NEW.obstime or validtime IS NULL);
    else		
	INSERT INTO RiverStatus
	VALUES ( NEW.lid, NEW.pe, NEW.dur, NEW.ts, NEW.extremum, -1., 
	NEW.obstime, NULL, NEW.value);            
    end if;
				    
RETURN NEW;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------
--
--	obs_river_upd.sql
--	This function updates the latest observed value in the
--      RiverStatus table for the given location.
--      Only do the update if the value or its time have changed.
--

CREATE OR REPLACE FUNCTION obs_river_upd () RETURNS TRIGGER AS '
DECLARE
    iret_code INT;
BEGIN
    if (NEW.value = OLD.value AND NEW.obstime = OLD.obstime) then 
        RETURN NEW;
    end if;
    iret_code := load_obs_river (NEW.lid, NEW.pe, NEW.ts);
RETURN NEW;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------
--
--	Procedure:	proc_latestobs.sql
--      updated for PostgreSQL August 2004
-- 
--     2/15/2005:   Fixed problem with duplicate key violates unique constraint

CREATE OR REPLACE FUNCTION latestobs
	(
	 varchar(8),
	 varchar(2),
	 integer,
	 varchar(2),
	 varchar(1),
	 timestamp,
	 float8,
	 varchar(1),
	 integer,
	 integer,
	 varchar(10),
	 timestamp,
	 timestamp,
	 integer
	)
	
RETURNS INT     AS '
	--
	--	Local variables
	--
	DECLARE lobs         latestobsvalue%ROWTYPE;
                newlid       ALIAS FOR  $1;
                newpe        ALIAS FOR  $2;
                newdur       ALIAS FOR  $3;
                newts        ALIAS FOR  $4;
                newextr      ALIAS FOR  $5;
                newobstime   ALIAS FOR  $6;
                newvalue     ALIAS FOR  $7;
                newrawqual   ALIAS FOR  $8;
                newqc        ALIAS FOR  $9;
                newrev       ALIAS FOR  $10;
                newprid      ALIAS FOR  $11;
                newprodtime  ALIAS FOR  $12;
                newposttime  ALIAS FOR  $13;
                do_update    ALIAS FOR  $14;

	--
	--	Process latestobs data
	--
BEGIN
         if do_update = 1 or do_update = 2 then
             UPDATE latestobsvalue SET
                 obstime        = newobstime,
                 value          = newvalue,
                 shef_qual_code = newrawqual,
                 quality_code   = newqc, 
                 revision       = newrev,
                 product_id     = newprid,
                 producttime    = newprodtime,
                 postingtime    = newposttime
                 WHERE lid = newlid and pe = newpe and
                 dur = newdur and ts = newts and
                 extremum = newextr and obstime <= newobstime;  
         else
             UPDATE latestobsvalue SET
                 obstime        = newobstime,
                 value          = newvalue,
                 shef_qual_code = newrawqual,
                 quality_code   = newqc, 
                 revision       = newrev,
                 product_id     = newprid,
                 producttime    = newprodtime,
                 postingtime    = newposttime
                 WHERE lid = newlid and pe = newpe and
                 dur = newdur and ts = newts and
                 extremum = newextr and obstime < newobstime; 
         end if;
	     
	 if (NOT FOUND) then    
             SELECT INTO lobs * FROM latestobsvalue
             WHERE lid = newlid
             AND   pe = newpe
             AND   dur = newdur
             AND   ts = newts
             AND   extremum = newextr;
             if (NOT FOUND) then    
                 INSERT INTO latestobsvalue
                 VALUES ( newlid,      newpe,       newdur,   newts,
                          newextr,     newobstime,  newvalue, newrev,
		          newrawqual,  newqc,       newprid,
		          newprodtime, newposttime);
	     end if;
	 end if;	

RETURN 0;
END;
'  LANGUAGE 'plpgsql';

-------------------------------------------------------------------------------

