Received: from localhost (postgresql.org [64.49.215.8]) by postgresql.org (Postfix) with ESMTP id 54ED9475E4A for ; Tue, 15 Oct 2002 12:27:36 -0400 (EDT) Received: from davinci.ethosmedia.com (davinci.ethosmedia.com [209.10.40.250]) by postgresql.org (Postfix) with ESMTP id A357B475D39 for ; Tue, 15 Oct 2002 12:27:35 -0400 (EDT) Received: from [63.195.55.98] (account ) by davinci.ethosmedia.com (CommuniGate Pro WebUser 3.5.9) with HTTP id 1787228; Tue, 15 Oct 2002 09:28:12 -0700 From: "Josh Berkus" Subject: Re: Messy Casts, Is there a better way? To: Larry Rosenman , pgsql-sql@postgresql.org X-Mailer: CommuniGate Pro Web Mailer v.3.5.9 Date: Tue, 15 Oct 2002 09:28:12 -0700 Message-ID: In-Reply-To: <1034676979.436.1.camel@lerlaptop.lerctr.org> MIME-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 8bit X-Virus-Scanned: by AMaViS new-20020517 X-Archive-Number: 200210/165 X-Sequence-Number: 9882 Larry, > contract_start date > contract_term int (term in MONTHS) > > I want to calculate the contract end date. I came up with: > CREATE FUNCTION "get_contract_end" (integer) RETURNS date AS 'SELECT > cast(contract_start + cast(cast(contract_term as text) || '' month'' > as > interval) as date) > FROM circuit > WHERE internal_id = $1;' LANGUAGE 'sql'; Not with those data types. Plus, there is an implicit conversion date --> timestamp --> date in the above, which can get you in trouble. You could use TIMESTAMP and INTERVAL instead: contract_start TIMESTAMP WITHOUT TIME ZONE contract_term INTERVAL select (contract_start + contract_term) as contract_end; Simple, neh? The only trick is on the end of saving the data. You have the user input an integer, then save (using RULES or your interface code): "interval"(cast($term as varchar) || ' months') This approach makes you do a little more work on the data entry end of things, but speeds up querying considerably. Also, should your company policy change in the future to permit contract terms in weeks or years, you will be ready to accomodate it. -Josh Berkus