[SQL] converting an oracle procedure to postgres
I have read the docs on converting Oracle to Postgres already. I'm a little confused though. I have a procedure in Oracle that just does some calculations and then does an update based on the calculations. The procedure doesn't return anything. It seems like in Postgres that everything has to be a function and has to return something. The following procedure is almost converted to Postgres format but it is not quite correct yet: CREATE OR REPLACE PROCEDURE p_updateorders (decimal, date) AS ' DECLARE orderno ALIAS FOR $1; orderdate ALIAS FOR $2; --defining variables v_subtotal decimal; v_taxstatus varchar(1); v_shipping varchar(12); v_shippingrate decimal; V_shippingcharge decimal := 0; v_taxrate decimal := 0; v_taxamtdecimal; v_totalamt decimal; BEGIN --taking the subtotal by calcualting with right price and qty of products in an order SELECT SUM( product_price(orderdate,product_no, qty) * qty) INTO v_subtotal FROM orderline WHERE order_no = orderno GROUP BY order_no; --finding if tax applicable or not SELECT tax_status INTO v_taxstatus FROM orders WHERE order_no = orderno; --finding the shipping method SELECT shipping_method INTO v_shipping FROM orders WHERE order_no = orderno; --get the tax rate IF upper(v_taxstatus) = ''Y'' THEN SELECT tax_rate INTO v_taxrate FROM tax WHERE state = (SELECT state FROM customer WHERE customer_no = (SELECT distinct customer_no FROM orders WHERE order_no = orderno)); END IF; v_taxamt := v_taxrate * v_subtotal; --get shipping cost IF upper(v_shipping) = ''2DAY-AIR'' THEN v_shippingrate := .08; ELSIF upper(v_shipping) = ''1DAY-AIR'' THEN v_shippingrate := .1; ELSIF upper(v_shipping) = ''GROUND'' THEN v_shippingrate := .05; ELSE v_shippingrate := 0; END IF; v_shippingcharge := v_shippingrate * v_subtotal; --calculating the total amount v_totalamt := v_subtotal + v_taxamt + v_shippingcharge; --now update the ORDERS table with new values UPDATE orders SET subtotal = v_subtotal, tax_amt = v_taxamt, shipping_charge = v_shippingcharge, total_amt = v_totalamt WHERE order_no = orderno; END; ' LANGUAGE 'plpgsql'; I know I have to relpace the word PROCEDURE with FUNCTION but then it wants me to put RETURNS but I don't want to return anything. I was thinking that I could just have it return integer and then after the last update statement put return 0. I'd rather not have it return a junk value though. What should I do? Thanks, Clint _ Never get a busy signal because you are always connected with high-speed Internet access. Click here to comparison-shop providers. https://broadband.msn.com ---(end of broadcast)--- TIP 2: you can get off all lists at once with the unregister command (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])
[SQL] assorted Postgres SQL/ORDBMS questions
1. You can raise exceptions but you can't catch exceptions in pgsql right? 2. Does Postgres support ORDBMS operations? Specifically I am wondering about the ability to define your own objects and create functions/procedures for the objects (e.g. object.method()). In Oracle I would use CREATE TYPE and CREATE TYPE BODY. Postgres' create type seems quite different than Oracle's version and they don't seem equivalent to each other. The Postgres version seems like it is for creating your own datatypes but not your own objets. I couldn't find any docs on this except on the SQL commands page. 3. Does it support nested tables? Again I couldn't find any info in the docs for this. 4. Can dates only be storied in -MM-DD format? I've looked over the documentation at http://www.postgresql.org/docs/7.3/static/functions-formatting.html and it seems that doing to_date(t_date,''DD-MON-'') should return 20-OCT-2003 but it returns 2003-10-20 no matter what I do. An example: CREATE OR REPLACE FUNCTION datetest() RETURNS date AS ' DECLARE t_date varchar; v_date date; BEGIN t_date := to_char(now(),''DD-MON-''); v_date := to_date(t_date,''DD-MON-''); RETURN v_date; END; ' LANGUAGE 'plpgsql'; SELECT datetest(); this returns: datetest -- 2003-10-20 I wanted it to return 20-OCT-2003 and the documentation suggests that I should be able to do that yet it doesn't actually do it. Now slightly different: CREATE OR REPLACE FUNCTION datetest() RETURNS varchar AS ' DECLARE t_date varchar; v_date date; BEGIN t_date := to_char(now(),''DD-MON-''); v_date := to_date(t_date,''DD-MON-''); RETURN t_date; END; ' LANGUAGE 'plpgsql'; SELECT datetest(); This returns: -- datetest 20-OCT-2003 This works fine but it is a varchar. I really want it to be stored like that but in a date type instead. Thanks for the answers! -Clint _ Add MSN 8 Internet Software to your current Internet access and enjoy patented spam control and more. Get two months FREE! http://join.msn.com/?page=dept/byoa ---(end of broadcast)--- TIP 3: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly
[SQL] create type input and output function examples
I've seen the docs for create type and an example of the syntax to create a type. What I haven't seen is the functions that are passed for the input and output elements. CREATE TYPE box (INTERNALLENGTH = 8, INPUT = my_procedure_1, OUTPUT = my_procedure_2); Now what would be in my_procedure1 and my_procedure2 procedures? I know they are just example placeholders above but I need to see a real example of what would be in those procedures to better understand what they should do. Thanks. _ Surf and talk on the phone at the same time with broadband Internet access. Get high-speed for as low as $29.95/month (depending on the local service providers in your area). https://broadband.msn.com ---(end of broadcast)--- TIP 4: Don't 'kill -9' the postmaster
[SQL] trigger conversion advice needed
I'm working on converting a simple trigger from Oracle to Postgres and I have a couple ofl questions that I need some help on please. First here's the Oracle trigger: CREATE OR REPLACE TRIGGER t_ship_date AFTER UPDATE OR INSERT OF order_date ON orders BEGIN UPDATE orders SET ship_date = working_5days(order_date); END; / When I was working on converting the trigger I noticed that Postgres doesn't have the OF table_attribute ON syntax support. I just want the trigger to fire when the order_date field in the order table is updated or inserted like it is specified in the Oracle trigger specification above. So I did this in Postgres: CREATE OR REPLACE FUNCTION t_ship_date() RETURNS TRIGGER AS ' BEGIN UPDATE orders SET ship_date = working_5days(new.order_date); RETURN NEW; END; ' LANGUAGE 'plpgsql'; I justed used new.order_date in the Postgres one version. I'm pretty sure that this isn't going to work, it will probably update every ship_date which is not what I want. I just want to update the ship_date when the record's order_date is updated. Is there some way in Postgres to specify a trigger to fire only when a certain field in a table is changed or inserted (like I had in the Oracle version)? I couldn't find anything for triggers to do that in the docs so I hope someone can shed some light on this for me. I thought maybe something like this could work too (probably closer to being correct): CREATE OR REPLACE FUNCTION t_ship_date() RETURNS TRIGGER AS ' BEGIN IF TG_OP = ''INSERT'' THEN UPDATE orders SET ship_date = working_5days(new.order_date) where order_no = new.order_no; ELSIF TG_OP =''UPDATE'' THEN UPDATE orders SET ship_date = working_5days(new.order_date) where order_no = old.order_no; END IF; RETURN NEW; END; ' LANGUAGE 'plpgsql'; The working_5days function just adds 5 business days to a date fyi. Now the second question I have is due to an error I keep getting when I try and make the trigger definition below: CREATE TRIGGER t_ship_date AFTER UPDATE OR INSERT ON orders EXECUTE PROCEDURE t_ship_date(); I always get a parse error at or near execute. What am I doing wrong? If I could get the trigger to compile then I could test it to see if it works the same as the Oracle version. I wouldn't even have to ask the first question if I could get it to compile but I thought I might as well ask anyway so I don't have to post another message. Thanks for the help. -Clint P.S. 7.3.4 is the postgres version on the server. _ Has one of the new viruses infected your computer? Find out with a FREE online computer virus scan from McAfee. Take the FreeScan now! http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 ---(end of broadcast)--- TIP 8: explain analyze is your friend
Re: [SQL] trigger conversion advice needed
Thanks for the advice Tom. I figured out why my create trigger statement wouldn't compile. Postgres expects a FOR EACH ROW or FOR EACH STATEMENT clause before the EXECUTE portion. Oracle assumes a statement level trigger unless you specify it to be for each row. In addition Oracle allows for specific columns to be monitored for updates like I had in the Oracle trigger (AFTER UPDATE OR INSERT OF order_date ON orders). Well I ended up adding FOR EACH STATEMENT to the Postgres version after the first email. I got a message back that said statement triggers weren't implemented in Postgres yet even though according to the 7.3 docs it can be used. I looked at the changelog for 7.4 and it said: "Add statement-level triggers (Neil) While this allows a trigger to fire at the end of a statement, it does not allow the trigger to access all rows modified by the statement. This capability is planned for a future release." I wonder if that means that I can specify FOR EACH STATEMENT and have it compile fine but it seems like that I can't acccess new and old though still in 7.4. I'll have to experiment with what you suggested and perhaps look into upgrading to 7.4 as well. Thanks, Clint Original Message Follows From: Tom Lane <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] CC: [EMAIL PROTECTED] Subject: Re: [SQL] trigger conversion advice needed Date: Wed, 26 Nov 2003 10:40:08 -0500 Received: from alias2.acm.org ([199.222.69.92]) by mc11-f24.hotmail.com with Microsoft SMTPSVC(5.0.2195.6713); Wed, 26 Nov 2003 07:40:10 -0800 Received: from sss.pgh.pa.us ([192.204.191.242])by alias2.acm.org (ACM Email Forwarding Service) with ESMTP id CRY73883for <[EMAIL PROTECTED]>; Wed, 26 Nov 2003 10:40:10 -0500 Received: from sss2.sss.pgh.pa.us ([EMAIL PROTECTED] [127.0.0.1])by sss.pgh.pa.us (8.12.10/8.12.10) with ESMTP id hAQFe819015058;Wed, 26 Nov 2003 10:40:08 -0500 (EST) X-Message-Info: JGTYoYF78jE74k1WFZAS8n73gEHv7D0r In-reply-to: <[EMAIL PROTECTED]> References: <[EMAIL PROTECTED]> Comments: In-reply-to "Clint Stotesbery" <[EMAIL PROTECTED]>message dated "Wed, 26 Nov 2003 11:51:42 +" Message-ID: <[EMAIL PROTECTED]> Return-Path: [EMAIL PROTECTED] X-OriginalArrivalTime: 26 Nov 2003 15:40:10.0631 (UTC) FILETIME=[936E3170:01C3B433] "Clint Stotesbery" <[EMAIL PROTECTED]> writes: > I'm working on converting a simple trigger from Oracle to Postgres and I > have a couple ofl questions that I need some help on please. First here's > the Oracle trigger: > CREATE OR REPLACE TRIGGER t_ship_date > AFTER UPDATE OR INSERT OF order_date ON orders > BEGIN >UPDATE orders >SET ship_date = working_5days(order_date); > END; It looks to me like this trigger implicitly assumes that an UPDATE command would only affect the row it was fired for --- which is not at all how Postgres will interpret such a command. (Alternatively, maybe the trigger actually does result in recomputing every row's ship_date? You would only notice if ship_date had been changed manually in some rows to be different from order_date + 5...) Guessing at what is actually wanted here, my inclination would be to use a BEFORE INSERT OR UPDATE trigger and to detect updates by change from OLD to NEW. The INSERT case would simply do NEW.ship_date := working_5days(NEW.order_date); RETURN NEW; The UPDATE case would look like IF NEW.order_date <> OLD.order_date THEN NEW.ship_date := working_5days(NEW.order_date); END IF; RETURN NEW; Pretty simple when you get the hang of it. > CREATE TRIGGER t_ship_date AFTER UPDATE OR INSERT ON orders > EXECUTE PROCEDURE t_ship_date(); > I always get a parse error at or near execute. You need to say FOR EACH ROW in there too. regards, tom lane _ Set yourself up for fun at home! Get tips on home entertainment equipment, video game reviews, and more here. http://special.msn.com/home/homeent.armx ---(end of broadcast)--- TIP 9: the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match
Re: [SQL] Create Trigger porting problem from Oracle to PostgreSQL7.3.2
Hi, I ran into the same thing last week. There is no way to specify that functionality in the trigger creation for Postgresql. You will have to code the trigger to detect when the specific field is updated. Tom Lane had suggested something for me last week. Check out the archive for the mailing list at http://archives.postgresql.org/pgsql-sql/2003-11/index.php and scroll down to November 26. Perhaps Tom will have more to say on this, he's pretty good at this stuff. On another note have you converted any instead of triggers from Oracle to Postgres? I'm not sure how to do that yet, maybe using rules but I'll save that for another message to the mailing list. -Clint Original Message Follows From: Doris Bernloehr <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] Subject: [SQL] Create Trigger porting problem from Oracle to PostgreSQL7.3.2 Date: Wed, 03 Dec 2003 17:57:51 +0100 MIME-Version: 1.0 Received: from mc10-f9.hotmail.com ([65.54.166.145]) by mc10-s5.hotmail.com with Microsoft SMTPSVC(5.0.2195.6713); Wed, 3 Dec 2003 09:12:31 -0800 Received: from hosting.commandprompt.com ([207.173.200.192]) by mc10-f9.hotmail.com with Microsoft SMTPSVC(5.0.2195.6713); Wed, 3 Dec 2003 09:11:53 -0800 Received: from postgresql.org (svr1.postgresql.org [200.46.204.71])by hosting.commandprompt.com (8.11.6/8.11.6) with ESMTP id hB3GwtS23721;Wed, 3 Dec 2003 08:59:18 -0800 Received: from localhost (neptune.hub.org [200.46.204.2])by svr1.postgresql.org (Postfix) with ESMTP id 98A82D1B4AEfor <[EMAIL PROTECTED]>; Wed, 3 Dec 2003 16:58:39 + (GMT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (neptune.hub.org [200.46.204.2]) (amavisd-new, port 10024) with ESMTP id 58440-05 for <[EMAIL PROTECTED]>; Wed, 3 Dec 2003 12:58:08 -0400 (AST) Received: from mail.gmx.net (imap.gmx.net [213.165.64.20])by svr1.postgresql.org (Postfix) with SMTP id 58C07D1D388for <[EMAIL PROTECTED]>; Wed, 3 Dec 2003 12:58:07 -0400 (AST) Received: (qmail 23665 invoked by uid 65534); 3 Dec 2003 16:57:51 - Received: from dsl-213-023-040-229.arcor-ip.net (EHLO gmx.net) (213.23.40.229) by mail.gmx.net (mp001) with SMTP; 03 Dec 2003 17:57:51 +0100 X-Message-Info: U2wzkPk8/jYj5Bpg8rsbCR+dCQ716btYhkbL2fD/ZgI= X-Original-To: [EMAIL PROTECTED] X-Authenticated: #718964 Message-ID: <[EMAIL PROTECTED]> User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 X-Accept-Language: en-us, en X-Virus-Scanned: by amavisd-new at postgresql.org X-Mailing-List: pgsql-sql Precedence: bulk Return-Path: [EMAIL PROTECTED] X-OriginalArrivalTime: 03 Dec 2003 17:11:53.0858 (UTC) FILETIME=[8C803E20:01C3B9C0] Hello I've got a problem in porting a trigger from Oracle into PostgreSQL. In Oracle you can choose between UPDATE and UPDATE OF COLUMN ... Is there a way to have the same functionality in PostgreSQL? Hope anyone can give me an advice. Doris ---(end of broadcast)--- TIP 8: explain analyze is your friend _ Winterize your home with tips from MSN House & Home. http://special.msn.com/home/warmhome.armx ---(end of broadcast)--- TIP 5: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faqs/FAQ.html
[SQL] Help converting Oracle instead of triggers to PostgreSQL
I have some instead of triggers in Oracle, some update instead of triggers and some insert instead of triggers. I was thinking that I could maybe use instead of rules in PostgreSQL to get the same effect. I converted the instead of trigger in Oracle into a PostgreSQL function below: CREATE OR REPLACE FUNCTION t_vproduct() RETURNS VOID AS ' DECLARE v_productsetno numeric; v_productno numeric; v_prodqty numeric; v_setqty numeric; oldqoh numeric; newqoh numeric; --cursor to to get set number, sub-product_no and their quantities in the productset prodset_cur CURSOR IS SELECT productset_no, product_no, prod_qty FROM productset WHERE productset_no = old.product_no; BEGIN oldqoh := old.qoh; newqoh := new.qoh; --opening and fetching the cursor in the variables OPEN prodset_cur; FETCH prodset_cur INTO v_productsetno, v_productno, v_prodqty; --checking if product is a set or individual --if it is not a set then update product table IF NOT FOUND THEN UPDATE product SET qoh = qoh - (oldqoh - newqoh) WHERE product_no = old.product_no; --if it is a SET then ELSIF FOUND THEN v_setqty := (oldqoh - newqoh); --SET quantity --loop updates each sub products qoh in the set LOOP UPDATE product --multiplying quantity of a product in a set with quantity of productset, to get total quantity of individual product in a set SET qoh = qoh - (v_prodqty * v_setqty) WHERE product_no = v_productno; FETCH prodset_cur INTO v_productsetno, v_productno, v_prodqty; EXIT WHEN NOT FOUND; END LOOP; CLOSE prodset_cur; END IF; RETURN; END; ' LANGUAGE 'plpgsql'; Then my guess for the rule is: CREATE OR REPLACE RULE r_vproduct AS ON UPDATE TO vproduct DO INSTEAD PERFORM t_vproduct(); I know that function isn't going to work the way I have it. In Oracle that function was defined as a trigger: CREATE OR REPLACE TRIGGER t_vproduct INSTEAD OF UPDATE ON v_product v_product is a view. Getting access to new and old is going to be at least one problem I can see. Perhaps I can pass in NEW and OLD into the t_vproduct function from the rule (DO INSTEAD PERFORM t_vproduct(new, old);). I'm not sure what to do. _ Take advantage of our best MSN Dial-up offer of the year six months @$9.95/month. Sign up now! http://join.msn.com/?page=dept/dialup ---(end of broadcast)--- TIP 9: the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match
Re: [SQL] Help converting Oracle instead of triggers to PostgreSQL
Hi Christoph, Thanks for the links but the techdoc links for converting from Oracle to PostgreSQL has 2 links that don't go to their intended targets anymore, one is in the 7.3 docs which is really limited (only covers simple things), and the Ora2Pg one I don't really get that well. As far as updateable views, that's why you need instead of triggers. Regular triggers can't be done on views. So if I make an instead of trigger on a view that's for updates then I have an updateable view. I figured it out last night and I was along the right track in my original post with using an instead of rule to call a function. The trick is that I have to pass in all the old.col and new.col stuff into the function that I call from the rule. In Oracle since the instead of stuff is a trigger I had access to the new.col and old.col stuff. To do it in PostgreSQL rules I had to pass it all in. I'm going to write a doc about the problems I've encountered during my conversion project and then submit it to the Postgres people I think (to who though?). My programming and tech writing background should help I hope. Thanks for the suggestions Christoph. -Clint Original Message Follows From: Christoph Haller <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] CC: [EMAIL PROTECTED] Subject: Re: [SQL] Help converting Oracle instead of triggers to PostgreSQL Date: Thu, 04 Dec 2003 17:16:32 MET Not sure if this is of any help ... AFAIK there are no updatable views in pg. But aside from that, I cannot see nothing what could not be done by a pg trigger function: CREATE TRIGGER name { BEFORE | AFTER } { event [OR ...] } ON table FOR EACH { ROW | STATEMENT } EXECUTE PROCEDURE func ( arguments ) Also try http://techdocs.postgresql.org/#convertfrom Converting from other Databases to PostgreSQL and/or http://openacs.org/search/search?q=oracle+to+pg+porting&t=Search HTH Regards, Christoph ---(end of broadcast)--- TIP 5: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faqs/FAQ.html _ Get holiday tips for festive fun. http://special.msn.com/network/happyholidays.armx ---(end of broadcast)--- TIP 5: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faqs/FAQ.html
Re: [SQL] converting Oracle scripts to PostgreSQL
Hi Gary, I went through a conversion from Oracle to PostgreSQL about 9 months ago. There's a little bit of documentation in the PostgreSQL manual http://www.postgresql.org/docs/7.4/interactive/plpgsql-porting.html or http://www.postgresql.org/docs/8.0/interactiveplpgsql-porting.html I had ment to submit docs to the manual but never got around to it since they could definately be expanded. The biggest issues I had for my project was that there were no statement level triggers and you couldn't do instead of triggers on views if my memory serves correct. plpgsql is really similar to Oracle plsql and in many cases you don't need to even change syntax. I could even you send the work I did since it was for school if you are interested. The reference manual for plpgsql can be found at: http://www.postgresql.org/docs/7.4/interactive/plpgsql.html or http://www.postgresql.org/docs/8.0/interactive/plpgsql.html Installing procedural languages: http://www.postgresql.org/docs/7.4/interactive/xplang.html or http://www.postgresql.org/docs/8.0/interactive/xplang.html triggers: http://www.postgresql.org/docs/7.4/interactive/triggers.html or http://www.postgresql.org/docs/8.0/interactive/triggers.html rules: http://www.postgresql.org/docs/7.4/interactive/rules.html or http://www.postgresql.org/docs/8.0/interactive/rules.html sql command syntax (for scripts): http://www.postgresql.org/docs/7.4/interactive/sql-commands.html or http://www.postgresql.org/docs/8.0/interactive/sql-commands.html Also try searching the mailing here: http://archives.postgresql.org/pgsql-sql/ You will probably find many of my old posts when I was converting Oracle to PostgreSQL. Hope this helps you get started. -Clint Original Message Follows From: "Gary Broadbent" <[EMAIL PROTECTED]> Reply-To: <[EMAIL PROTECTED]> To: Subject: [SQL] converting Oracle scripts to PostgreSQL Date: Wed, 19 Jan 2005 12:37:48 - Hi, I have a database in Oracle that I want to convert to PostgreSQL. I have exported the scripts used to create the tables, constraints and sequences in Oracle and wish to convert these to postgreSQL scripts now. Is there an easy way to do this? Regards, Gary. This email (and any attachments) is private and confidential, and is intended solely for the addressee. If you have received this communication in error please remove it and inform us via telephone or email. Although we take all possible steps to ensure mail and attachments are free from malicious content, malware and virii, we cannot accept any responsibility whatsoever for any changes to content outwith our administrative bounds. The views represented within this mail are solely the view of the author and do not reflect the views of Graham Technology as a whole. Graham Technology plc http://www.gtnet.com ---(end of broadcast)--- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED] ---(end of broadcast)--- TIP 3: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly
Re: [SQL] Moving from Transact SQL to PL/pgSQL
For Oracle info, check out one of my recent posts: http://archives.postgresql.org/pgsql-sql/2005-01/msg00231.php For TSQL, well, I was involved in project where we converted an Oracle db (with procs, functions, triggers, etc) to PostgreSQL and MS Sql Server. plpgsql and plsql are close enough where it isn't too hard to convert between the two. TSQL and plpgsql are quite different. -Clint Original Message Follows From: "Kevin Duffy" <[EMAIL PROTECTED]> To: Subject: [SQL] Moving from Transact SQL to PL/pgSQL Date: Mon, 24 Jan 2005 12:14:22 -0500 Hello: I am starting a project using Postgres. The requirements are very similar to work I have done in the past using M$-SQL. Therefore, there are many Transact SQL stored procedures I need to port over to PL/pgSQL. Where would I find documentation on PL/pgSQL, with examples? How close to Oracle PL-SQL is Postgres? Would a Oracle PL-SQL book cover the basics? Remember be kind to the newbee. Kevin Duffy ---(end of broadcast)--- TIP 8: explain analyze is your friend