Swapping Timestamp for Timestamp With Time zone causes error with jdbc - postgresql

I'm looking for a way around an unexpected problem. We have a third party app that is loading data into our database. It's our code that creates the postgresql schema, the third party doesn't provide it. With TIMESTAMP columns this works, but we'd much prefer to use TIMESTAMP WITH TIME ZONE.
We tried to do this by changing the default TimeZone of the user. The following SQL works through psql. The fixed timezone for the user is assumed:
insert into AAA (FOO,BAR) select 'X','2022/03/19 21:15:25' where not exists (select 1 from AAA where FOO = 'X'
But the app is raising an exception:
Caused by: org.postgresql.util.PSQLException: ERROR: column "BAR" is of type timestamp with time zone but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
The timezone of the user was set with:
insert into pg_db_role_setting (setrole, setdatabase, setconfig) values (16394, 0, '{TimeZone=+10}')
And in psql, subsiquent calls to SELECT now() return in +10 timezone as desired.
Firstly, why could JDBC be hitting an error when the psql doesn't on the same insert statement?
Secondly is there any workaround for this without changing the program source code?

Related

Postgres INSERT timestamp with UNION ALL error

Good day!
I need to export/import data from SQL Server 2019 to AWS RDS running PostgreSQL 13.3
It's just a few hundred rows from a handful of tables.
This is my first ever encounter with Postgres, so I decided to simply script data as "INSERT ... SELECT", as I would with SQL Server... and I've looked into AWS Glue, RDS S3 Import - it all seems waaay too much for what I need.
I am using DBeaver v21 for of this as I have easy access to both source and destination DBs.
This I tested with success:
CREATE TABLE public.invoices (
invoiceno int8 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
terminalid int4 NOT NULL,
invoicedate timestamp NOT NULL,
description varchar(100) NOT null
);
INSERT INTO public.invoices(InvoiceNo,TerminalID,InvoiceDate,Description)
SELECT 7 as invoiceno , 5 as terminalid , '2018-10-24 21:29:00' as invoicedate , N'Coffe and cookie' as description
-- Updated Rows 1
-- No problem here
I scripted the rest of the data with UNION ALL, like so (shortened example) :
INSERT INTO public.invoices(InvoiceNo,TerminalID,InvoiceDate,Description)
SELECT 7 as invoiceno , 5 as terminalid , '2018-10-24 21:29:00' as invoicedate , N'Coffe and cookie' as description
UNION ALL
SELECT 1000, 5 , '2018-10-24 21:29:00' , N'Tea and crumpets'
and now I get:
SQL Error [42804]: ERROR: column "invoicedate" is of type timestamp without time zone but expression is of type text
Hint: You will need to rewrite or cast the expression.
Position: 118
I do see in the message that it can be "fixed" with a CAST (or rewrite!)....
but how come Postgres can convert 1 row implicitly, yet 2 rows is impossible?
why does this fail when more than 1 row is being inserted? - it clearly knows how to convert text -> date ...
I tried using VALUES, CTE, derived tables with no success.
As I have to spend more time with postgres - I really would like to understand what's going on here. Is my syntax wrong (works fine SQL Server), is DBeaver messing up something with my data, etc...?
Any suggestions would be appreciated.
Thank you
'2018-10-24 21:29:00' is a string value and Postgres is a bit more picky about correct data types then SQL Server.
You need to specify the value as a proper timestamp constant,
timestamp '2018-10-24 21:29:00'
Note that you can write that in a bit more compact form using a values clause:
INSERT INTO public.invoices(InvoiceNo,TerminalID,InvoiceDate,Description)
values
(7, 5, timestamp '2018-10-24 21:29:00', 'Coffe and cookie'),
(1000, 5 , timestamp '2018-10-24 21:29:00' , 'Tea and crumpets');
The reason of such behaviour is in order of compilation.
In situation when you use VIEW first are compiled querys in view and types of columns (names too) in view is taken from the first part of a "view" (the first SELECT command).
So, you have got text instead of timestamp and it doesn't match to inserted table type.
MSSQL compiler is a little bit smarter :-).
In first example you have simple INSERT INTO ... SELECT ....
and compiler at once expect timestamp type - so , it not rise any compilation error (but error can ocure in execution time when the data do not pass rules of automatic conversion).

Casting String type to Unix Date Amazon Athena

I'm looking to get a result in Amazon Athena were I can count the quantity of users created by day (or maybe by month)
But previous that I have to convert the unix timestamp to another date format. And this is where i fail.
My last goal is to convert this type of timestamp:
1531888605109
In something like:
2018-07-18
According to Epoch Converter
But when I try to apply the solution i saw in this quiestion: Casting unix time to date in Presto
I got the error:
[Simba]AthenaJDBC An error has been thrown from the AWS Athena client. SYNTAX_ERROR: line 1:13: Unexpected parameters (varchar) for function from_unixtime. Expected: from_unixtime(double) , from_unixtime(double, bigint, bigint) , from_unixtime(double, varchar(x)) [SQL State=HY000, DB Errorcode=100071]
This is my query:
select cast(from_unixtime(created)as date) as date_creation,
count(created)
from datalake.test
group by date_creation
Maybe I've to cast over the sctring because the data type of the field is not a date.
My table description: Link to the table description
line 1:13: Unexpected parameters (varchar) for function from_unixtime. Expected: from_unixtime(double)
This means that your timestamps -- even though they appear numeric -- are varchars.
You need to add a CAST to cast(from_unixtime(created)as date), like:
CAST(from_unixtime(CAST(created AS bigint)) AS date)
Note: When dealing with time-related data, please have in mind that https://github.com/prestosql/presto/issues/37 is not resolved yet in Presto.

Postgres timestamp formatting in query

I am migrating a code with its own ORM from Db2 to postgres. I have a query that executes the following sql on postgres 10 -
SELECT * FROM TriggerQueue
WHERE TriggerQueue.atServerStartup = 'Y'
AND (TriggerQueue.scheduledatetime > '2018-06-21 20.02.57.827' OR
TriggerQueue.scheduleDateTime is null) AND TriggerQueue.inputQueue = 'N'
but the pgadmin is showing the following error:
ERROR: invalid input syntax for type timestamp: "2018-06-21
20.02.57.827"
LINE 3: AND (TriggerQueue.scheduledatetime > '2018-06-21 20.02.57.8...
^
SQL state: 22007
I'm guessing the timestamp format is wrong based on sql state, but I'm not sure how to format the value. Any insight on this would be very helpful.
EDIT : Timestamp field in pg is of the type timestamp without timezone. Pgadmin shows size of 6.
Use a proper timestamp literal:
timestamp '2018-06-21 20:02:57.827'
Note the : to separate hours, minutes and seconds

How to insert current datetime in postgresql insert query [duplicate]

This question already has answers here:
in postgres, can you set the default formatting for a timestamp, by session or globally?
(3 answers)
Closed 6 years ago.
INSERT into Group (Name,CreatedDate) VALUES ('Test',UTC_TIMESTAMP(), 1);
This is the query I have used for mysql to insert current date time.
When I am using this in postgresql, I am getting below error.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
********** Error **********
ERROR: function utc_timestamp() does not exist
SQL state: 42883
I have tried like below using now(), however it is inserting like "2016-07-07 17:01:18.410677". I need to insert in 'yyyymmdd hh:mi:ss tt' format.
INSERT into Group (Name,CreatedDate) VALUES ('Test',UTC_TIMESTAMP(), 1);
How to insert current date time in insert query of postgresql in above format ?
timestamp (or date or time columns) do NOT have "a format".
Any formatting you see is applied by the SQL client you are using.
To insert the current time use current_timestamp as documented in the manual:
INSERT into "Group" (name,createddate)
VALUES ('Test', current_timestamp);
To display that value in a different format change the configuration of your SQL client or format the value when SELECTing the data:
select name, to_char(createddate, 'yyyymmdd hh:mi:ss tt') as created_date
from "Group"
For psql (the default command line client) you can configure the display format through the configuration parameter DateStyle: https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-DATESTYLE
For current datetime, you can use now() function in postgresql insert query.
You can also refer following link.
insert statement in postgres for data type timestamp without time zone NOT NULL,.
You can of course format the result of current_timestamp().
Please have a look at the various formatting functions in the official documentation.

Can't enter date into postgres field with datatype reltime

I'm trying to make an insert into postgres 8.4.13
insert into my_table (id, hour_memo) values (1,'17:30:00.000000 +01:00:00');
hour_memo is 'reltime datatype'
During the execution of the insert task i have this trouble:
ERROR: invalid input syntax for type reltime: "17:30:00.000000 +01:00:00"
I have absolutely no idea on how to do this?
The answer is that reltime doesn't support time zones, so the "+01..." thing is breaking it. Still - using reltime type is bad idea, and should be replaced by some normal type.