Dates, Timestamp and Oracle BI Answers Filters
March 6th, 2009 by Mark Rittman
I was working with a customer today who had brought in a new Oracle source into their OBIEE physical layer. The source had several tables with date columns that used the DATE datatype, and these tables were then used to create a simple dimensional model, like the one below.

Everything worked well, until they created a request with a filter on the date column. Remember that the column in Oracle is a DATE datatype, yet the filter added by Answers below adds a TIMESTAMP to the predicate.

Now the reason that this is an issue, is if you’ve got an index defined on the date column. If you let Answers generate the query as it is, you end up with SQL looking like this:
-------------------- Logical Request (before navigation):
RqList distinct
Items.Order ID as c1 GB,
Items.Order Date as c2 GB
DetailFilter: Items.Order Date = TIMESTAMP '2007-04-12 00:00:00.000'
OrderBy: c1 asc, c2 asc
+++Administrator:480000:48000b:----2009/03/06 21:27:26
-------------------- Sending query to database named orcl2 (id: <<309826>>):
select distinct T6622.ORDID as c1,
T6631.ORDERDATE as c2
from
ITEMS T6622,
ORDERS T6631
where ( T6622.ORDID = T6631.ORDID and T6631.ORDERDATE = TIMESTAMP '2007-04-12 00:00:00' )
order by c1, c2
which will mean that your index won’t get used, unless you create a corresponding function-based index on the date column. It also screws up partition elimination as well, which can seriously impact the response time of your query.
The answer to this problem is to go back to the physical model in Oracle BI Administrator, and change the DATETIME datatype that OBIEE assigns to Oracle DATE datatypes by default, to an OBIEE DATE datatype, like this:

This altered datatype then propagates through to the business model and mapping layer, and then the presentation layer of the model. After restarting the Oracle BI Server just to be on the safe side, reloading the server metadata in Oracle BI Answers, I go to create the same report. To my surprise though, the filter prompt still adds a timestamp to my choice of date.

Cue several hours of fiddling with column formulas in Answers, wrapping the filter value in a CAST function and so on, all of which only partially solved the problem and usually ended up with either the predicate or the table column being wrapped in a function call, which again cancelled out the index. In the end, we just tried dropping the column from the business model and mapping layer, and then adding it back in again from the physical layer.

Now, after adding the new column to the presentation layer, saving the repository and then reloading the server metadata in Answers, when I create a new request in Answers the filter prompt just uses the date on its own.

Then, if I take a look at the SQL in the query log, we can see that the predicate is just a date. Checking the execution plan afterwards shows that the index is indeed being used.
-------------------- Logical Request (before navigation):
RqList distinct
Items.Order ID as c1 GB,
Items.ORDERDATE as c2 GB
DetailFilter: Items.ORDERDATE = DATE '2007-04-12'
OrderBy: c1 asc, c2 asc
+++Administrator:300000:300005:----2009/03/06 21:46:19
-------------------- Sending query to database named orcl2 (id: <<12826>>):
select distinct T6622.ORDID as c1,
T6631.ORDERDATE as c2
from
ITEMS T6622,
ORDERS T6631
where ( T6622.ORDID = T6631.ORDID and T6631.ORDERDATE = TO_DATE('2007-04-12' , 'YYYY-MM-DD') )
order by c1, c2
So the moral of the story there is, if you’re bringing Oracle data in and it’s got DATE datatypes, make sure you correct the DATETIME datatypes that the import process assigns to them in the physical model, otherwise you’ll hit this same problem around superfluous TIMESTAMPs. If you’ve already built your logical model before you find this issue, make sure you delete and the re-add the date columns after you correct the physical model datatype, otherwise Answers will still go on using TIMESTAMPs even if you change the repository model and even refresh the Answers metadata. Simple once you know how, but it took us a good few hours to sort out.
The story didn’t end there though. The customer also set up a session variable that held, for each user, yesterday’s date. They populated this within an initialization block that selected against the SYSDATE pseudo-column, truncating it and taking 1 off to return yesterday’s date.

As you can see, again by default OBIEE assigns it a DATETIME datatype, which will cause the same problem as before if we try and use it in a filter. No amount of TO_DATE or CAST as DATE around the SQL would turn it into a plain old DATE datatype, so in the end we wrapped a TO_CHAR around it and converted it into the correct CHAR format for our database’s NLS_DATE settings, like this:

Now, if we include the session variable in a filter, like this:

The resulting SQL generated by the BI Server includes this CHAR version of the date directly in the query, which Oracle then implicitly converts to a date datatype because we’re using the correct date format for the database’s NLS_DATE setting.
-------------------- Logical Request (before navigation):
RqList distinct
Items.Order ID as c1 GB,
Items.ORDERDATE as c2 GB
DetailFilter: Items.ORDERDATE = '06-MAR-2009'
OrderBy: c1 asc, c2 asc
+++Administrator:300000:300006:----2009/03/06 21:58:47
-------------------- Sending query to database named orcl2 (id: <<12934>>):
select distinct T6622.ORDID as c1,
T6631.ORDERDATE as c2
from
ITEMS T6622,
ORDERS T6631
where ( T6622.ORDID = T6631.ORDID and T6631.ORDERDATE = '06-MAR-2009' )
order by c1, c2
Checking the execution plan for this new query, it is indeed using the index we created. Now obviously, this is a “dangerous thing” as we’re making the assumption that our database, or more correctly database client software, will always keep using this same NLS_LANG setting, but given that I can’t see any other way of getting the BI Server to store the date session variable as a date rather than date and time, it’s a working solution that solved the immediate problem.
So, a day of fiddling around with dates, and thanks to John Minkjan, Venkat and Christian Berg who chipped in with some advice. If anyone else faces the same issue, hopefully this posting will be of use.


March 9th, 2009 at 3:14 pm
Very useful information!
Question on session monitor log you are showing:
My log only shows the query sent to the database but yours includes the Logical Request.
What setting are you using to get that?
I’m using 10.1.3.2
The loglevel is set to 2.
Thanks
March 10th, 2009 at 12:18 pm
Very useful information Mark!
We went through the same issue 2 months back in our project. We converted all our date columns to time stamp. :O
@John Tesson loglevel 3 gives you logical execution plan. They might be using it show the logical request, though loglevel 2 is teh one advised by Oracle.
March 12th, 2009 at 1:56 pm
Useful post, it reminded me that we had to fix this issue as it got put in the backburner. It wasn’t a major issue for us as the date dimension it’s very small so the full scan might actually speed things up. We applied the fix but noticed a side effect. You can’t use the TO_CHAR variable in prompts (say to defaul a date prompt) as it seems OBIEE doesn’t like the DD-MON-YYYY format. We raised an SR for this Oracle and a bug has been raised.
Going back to the initial issue I think this is also a bug. If the data type of the resulting SQL is DATE why would OBIEE initialise the variable as a TIMESTAMP?
April 1st, 2009 at 3:27 pm
I changed our Usage Tracking columns, END_DT and START_DT from DATETIME to DATE for the S_NQ_ACCT table but it caused usage tracking to fail in startup of the server.
2007-02-23 19:23:41
[43030] : Siebel Analytics Server started. Version: 7.8.2.5575.
2007-02-23 19:50:47
[59053] Usage Tracking stopped because the specified Usage Tracking table contained the wrong number of columns or a column with an inappropriate data type.
The solution was to set the Physical Layer columns for this table back to DATETIME. Too bad though because they are a pain to work with as DATETIME.
April 2nd, 2009 at 9:56 pm
So,what type of “date” a presentation variable returns??if we select a date from a calendar?
tnks…
April 8th, 2009 at 11:35 pm
I am trying to set up a “Year MOnth Start Date” as a date datatype in the physical alyer. However when I add this column in a multi-select box in OBI teh default format is always in the format ‘YYYY-MM-DD’ and the dates in the multi-select box are in the format MM/DD/YYYY. When I choose a date from the right to the left of the multi-select and click on it changes the format back to ‘YYYY-MM-DD’. I am not sure how to make the formats uniform. ANy ideas around this?
July 30th, 2009 at 3:45 pm
We have ran into yet another problem with this issue. With a calendar prompt or a regular dropdown prompt for the date field has the format mm/dd/yyyy. And when we put this value into a presentation variable and want to display it in the report, OBIEE comes with its own format of yyyy-mm-dd. Is there way to change how the presentation variable looks to match the prompt? Thank you!
February 22nd, 2010 at 2:56 am
Click on the Advanced button of your filter, and explicitly CAST the Session Variable to a date
ie. Time.”Forecast Month End Date” = CAST (VALUEOF(“DW_PREVIOUS_FORECAST_MONTH”) AS DATE )
This will cause the following SQL using TRUNC which allows the DATE index to be used.
AND t497896.fscl_mnth_end_dt =
TRUNC (TIMESTAMP ’2010-01-31 00:00:00′)
August 31st, 2010 at 3:48 pm
If this could help somebody.
We had a different request but related:
We have 3 Session Variables defined: Day, Month and Year (separately). And we needed to use them in an answers request against a date column (something like Trans.”Trans Date” >= Day-Month-Year).
After read this blog we soluted using a “SQL Expression” type filter with this expression (on the “Trans Date” column):
VALUEOF(NQ_SESSION.DAY)||’-'||(CASE VALUEOF(NQ_SESSION.MONTH) WHEN ‘ENE’ THEN ‘JAN’ WHEN ‘ABR’ THEN ‘APR’ WHEN ‘AGO’ THEN ‘AUG’ WHEN ‘DIC’ THEN ‘DEC’ ELSE VALUEOF(NQ_SESSION.MONTH) END)||’-'||VALUEOF(NQ_SESSION.YEAR)
Take care with your date format, in our case the Oracle Database format date is: “DD-MON-YYYY” (for that reason you see we are transforming the month name to english).