How to avoid an explicit cast when selecting from an Esper window? - complex-event-processing

Is there a way when selecting from a window to avoid an explicit cast?
TradeEvent is a Java object that has a field tallyEvent of type TallyEvent and TallyWindow is made from TallyEvent ... but the EPL below still requires a cast.
create window TallyWindow.std:unique(symbol, trader) as TallyEvent;
on TallyEvent merge TallyWindow insert select *;
The following epl:
insert into TradeEvent
select t tallyEvent from TallyWindow as t;
results in:
Assignment conversion not possible from type "com.espertech.esper.common.client.EventBean" to type "events.TallyEvent"
requiring a cast:
insert into TradeEvent
select cast(t, TallyEvent) tallyEvent from TallyWindow as t;
Is there a way to avoid having to cast t to a TallyEvent?

Related

PostgreSQL execute SELECT * FROM (t as a); return ERROR: syntax error at or near ")"

Why these SQLs can't work in PostgreSQL?
SELECT * FROM (t as a);
or
SELECT * FROM (t);
ERROR: syntax error at or near ")"
Those SQLs work well in MySQL.
Well, it's invalid SQL.
If you want to give the table an alias you need to use from t as a.
The form from (....) requires a valid query inside the parentheses and t as a (or just t) is not a valid query. Additionally: a derived table (which is what (...) defines) requires an alias. So at least it has to be from (...) as bla
To get all rows and all columns from a table the SQL standard provides the shortcut table some_table which is supported by Postgres.
So the following would be valid:
select * from (table t) as a
Typically, table alias' are applied where there is a join. For example:
SELECT alias1.login_name, alias2.name
FROM tablename1 AS alias1
JOIN tablename2 AS alias2
ON alias1.id = alias2.role_id;
To apply an alias to a single table:
SELECT * FROM tablename AS alias;
..will do it for you, no need for parentheses.
You can confirm/test by example below if value is an integer:
SELECT * FROM tablename AS alias
WHERE alias.colum = value;
..or if value is a string:
SELECT * FROM tablename AS alias
WHERE alias.colum = 'value';
postgreSQL is strongly-typed, so the first example above will work for Int and Bool values, however if you have Date or other values, you may need to apply type casting. See this link for helpful info*: www.postgresqltutorial.com/postgresql-tutorial/postgresql-cast.
**Remember: For psql strings, always use single quotes for values, use double quotes for table names and column names.

Is it possible to cast from one enum to another in PostgreSQL

I need to populate a new table in a second schema from an existing one, but having problems casting the "schema1.a.disclosure_level" column enum to the "schema2.b.disclosure_level" enum. A cast via ::text or :: varchar did not help. Casting to ::schema1.a.disclosure_level raises a cross-database reference error.
INSERT INTO schema1.a (id, disclosure_level)
SELECT schema2.b.id, schema2.b.disclosure_level
FROM schema2.b;
Any ideas?
#Bergi showed me the solution.
INSERT INTO schema1.a (id, disclosure_level)
SELECT schema2.b.id, schema2.b.disclosure_level::text:schema1.disclosure_level_enum
FROM schema2.b;
where my fault was to use the column name instead of the enum type definition in the cast: schema1.disclosure_level_enum (type) instead of schema1.a.disclosure_level (column)!
From here:
https://www.postgresql.org/docs/current/datatype-enum.html
8.7.3. Type Safety
Each enumerated data type is separate and cannot be compared with other enumerated types.
Example:
CREATE TYPE animal AS ENUM ('dog', 'cat', 'rabbit');
CREATE TYPE animal_2 AS ENUM ('dog', 'cat', 'rabbit');
create table enum_test(id integer, a animal, a2 animal_2);
insert into enum_test values (1, 'dog', 'cat');
select a::animal from enum_test ;
a
-----
dog
select a::animal_2 from enum_test ;
ERROR: cannot cast type animal to animal_2
LINE 1: select a::animal_2 from enum_test ;
So the answer is no you can't cast one enum to another.
It can be possible if you cast to VARCHAR as first and second to another enum
"valueType" = NEW."valueType"::VARCHAR::"enum_second"

PostgreSQL nested UDTs ans CAST syntax

I have few UD types:
CREATE TYPE SOME_TYPE AS (
aaa INT,
bbb TEXT
);
CREATE TYPE SOME_ANOTHER_TYPE AS (
ccc int,
ddd SOME_TYPE
);
CREATE TYPE SOME_ANOTHER_DAMNIT_TYPE AS (
eee int,
fff SOME_ANOTHER_TYPE
);
Okay, i can make first from SQL:
select '(123,blablabla)'::SOME_TYPE;
And i can make second:
select '(456, "(123,blablabla)")'::SOME_ANOTHER_TYPE;
But if i try to make third...
select '(789,"(456, "(123,blablabla)")")'::SOME_ANOTHER_DAMNIT_TYPE;
... pl throw error:
[22P02] ERROR: malformed record literal: "(456, "(123 Подробности:
Unexpected end of input.
Question: how to make third type without plpgsql? I need it for calling from jdbc, to transfer object. I know, i can 'flatten' this object, but i want transfer it 'as is'.
The problem is that you have nested the quotes without escaping the inner quotes. You could that like so:
select '(789,"(456, ""(123,blablabla)"")")'::SOME_ANOTHER_DAMNIT_TYPE;
i.e. by doubling the ".
For your case, I would suggest to avoid representing your record values as text only to cast them as your type later on. You can specify the record values directly, without going through text like so:
select (789,(456, (123,'blablabla')))::SOME_ANOTHER_DAMNIT_TYPE;

How to convert self-defined types, e.g. geometry, to and from String?

There is geometry type column in database like Postgis or h2gis(I am using it).
In the console provided by database, I can create a geometry value with select ST_GeomFromText('POINT(12.3 12)', 4326).
Or select a column with geometry type simply by select * from geom.
However I don't know how to insert a geometry value (a string actually) into a table or the opposite direction conversion.
There are also several miscellaneous question below.
Here is the table definition in slick:
class TableSimple(tag:Tag) extends Table[ (Double,String,String) ](tag,"tb_simple"){
def col_double = column[Double]("col_double",O.NotNull)
def col_str = column[String]("col_str",O.NotNull)
def geom = column[String]("geom",O.DBType("Geometry"))
def * = (col_double,col_str,geom)
}
1. About select
The most simple one:
sql" select col_double,col_str, geom from tb_simple ".as[(Double,String,String)]
won't work unless casting geom to string explicitly like:
sql" select col_double,col_str, cast( geom as varchar) from tb_simple ".as[(Double,String,String)]
The first sql throws the error java.lang.ClassNotFoundException: com.vividsolutions.jts.io.ParseException
Q1: How does slick know com.vividsolutions.jts.io.ParseException (it is lib used by h2gis)? Is it an error on the server side or client side(slick side)?
Q2: How to convert/treat column geom as string without writing too much code(e.g. create a new column type in slick)?
2. About insert
First of all the following sql works
StaticQuery.updateNA(""" insert into tb_simple values(11,'abcd',ST_GeomFromText('POINT(5.300000 1.100000)', 4326)) """).execute
I hope code like TableQuery[TableSimple] += (10.3,"hello","ST_GeomFromText('POINT(0.300000 1.100000)'") would work but it doesn't.
It shouldn't because slick translate it to
insert into tb_simple values(11,'abcd','ST_GeomFromText(''POINT(5.300000 1.100000)'', 4326)')
Notice the function ST_GeomFromText become a part of string, that's why it doesn't work.
Q3: Can I implant a string directly for a column instead of wrapped with '' in slick?
I hope I can insert a row as easy as TableQuery[TableSimple] += (10.3,"hello","ST_GeomFromText('POINT(0.300000 1.100000)'") or similar code.
Q4 What's the most convenient way in Slick to implement bidirectional conversion to and from String for a geometry or other self-defined column in the database?
Answering you main question: Slick-pg offers mapping of geometry types in the db to actual geometry types in your model.
It works for Postgis, but maybe it can also work with H2Gis.
You can find slick-pg at https://github.com/tminglei/slick-pg

Postgres query error

I have a query in postgres
insert into c_d (select * from cd where ak = '22019763');
And I get the following error
ERROR: column "region" is of type integer but expression is of type character varying
HINT: You will need to rewrite or cast the expression.
An INSERT INTO table1 SELECT * FROM table2 depends entirely on order of the columns, which is part of the table definition. It will line each column of table1 up with the column of table2 with the same order value, regardless of names.
The problem you have here is whatever column from cd with the same order value as c_d of the table "region" has an incompatible type, and an implicit typecast is not available to clear the confusion.
INSERT INTO SELECT * statements are stylistically bad form unless the two tables are defined, and will forever be defined, exactly the same way. All it takes is for a single extra column to get added to cd, and you'll start getting errors about extraneous extra columns.
If it is at all possible, what I would suggest is explicitly calling out the columns within the SELECT statement. You can call a function to change type within each of the column references (or you could define a new type cast to do this implicitly -- see CREATE CAST), and you can use AS to set the column label to match that of your target column.
If you can't do this for some reason, indicate that in your question.
Check out the PostgreSQL insert documentation. The syntax is:
INSERT INTO table [ ( column [, ...] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) | query }
which here would look something like:
INSERT INTO c_d (column1, column2...) select * from cd where ak = '22019763'
This is the syntax you want to use when inserting values from one table to another where the column types and order are not exactly the same.