How to compare two timestamp columns in a Gremlin Java query - java

Is there a way to do something like that in Gremlin traversals?
I would have thought it would be obvious, but it seems I was wrong.
I have a table containing two dates (both are timestamps), and I would like to select only the records having one greater than the other one. Something like:
has('date_one', P.gt('date_two'))
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: timestamp with time zone > character varying
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Then the second argument is not translated into the value of the column 'date_two'.
Based on the answer 1, the full request becomes:
g.V().hasLabel('File').where(or (
__.out('has_Ref1').hasNot('date_one'),
__.out('has_Ref1').as('s1', 's2').where('s1', gt('s2')).by('date_two').by('date_one')))
.as('file').out('has_Ref1').as('ref1').out('has_Content').as('data').select('file','ref1','data')
But in this case: A where()-traversal must have at least a start or end label (i.e. variable): [OrStep([[VertexStep(OUT,[has_Ref1],vertex), NotStep([PropertiesStep([date_one],value)])], [VertexStep(OUT,[has_Ref1],vertex)#[s1, s2], WherePredicateStep(s1,gt(s2),[value(date_two), value(date_one)])]])]
I guess the second argument of the or clause must be a boolean. Then if I try to add '.hasNext()', I've got the following exception:
g.V().hasLabel('File').where(or (
__.out('has_Ref1').hasNot('date_one'),
__.out('has_Ref1').as('s1', 's2').where('s1', gt('s2')).by('date_two').by('date_one').hasNext()))
.as('file').out('has_Ref1').as('ref1').out('has_Content').as('data').select('file','ref1','data')
groovy.lang.MissingMethodException: No signature of method: static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.or() is applicable for argument types: (org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal...) values: [[VertexStep(OUT,[has_Ref1],vertex), NotStep([PropertiesStep([date_one],value)])], ...]

The has() step doesn't quite work that way as the P deals with a constant value supplied to it and doesn't treat that value as a property key. You would want to use where() step in this case I think so that you could take advantage of traversal induced values:
gremlin> g.addV('person').property('d1',1).property('d2',2).
......1> addV('person').property('d1',2).property('d2',1).iterate()
gremlin> g.V().as('x','y').where('x', gt('y')).by('d1').by('d2').elementMap()
==>[id:3,label:person,d1:2,d2:1]

Why don't you ask Postgres if the data_one is bigger than date_two
SELECT '2019-11-20'::timestamp > '2019-11-01'::timestamp;
?column?
----------
t
(1 row)
Time: 10.246 ms
this provides you a boolean value

I am assuming you are talking about a columns in a single table.
I have mostly worked with graphDB with gremlin but I think it will still fit right.
do your thing to get the table of concern
g.V().has(...).has()...
then just project the same data twice by using project directly or using as & select
...as('named1', 'named2').select('named1')
it is creating two copies of same data in the flow and then you can compare them on different basis like
...where('named1', gt('named2')).by('value1').by('value2')
above part in literal english means that bring me only those from selected where value1 of named1 is greater than value2 of named2
If you give only one by then it will compare same property

Related

Rounding issue when dividing a COUNT value by another value using jooq

When using SQL, I can run a simple query such as the query below with no issue, it returns an answer to 4 decimal places:
SELECT(COUNT(ID)/7) FROM myTable;
If the count above returns a value of 12, the returned select value is 1.7143 in workbench.
My issue occurs when I use jooq to do this calculation:
dsl.select(count(MYTABLE.ID).divide(7).from(MYTABLE).fetch();
The above code returns me a value of 1, whereas I want a value of 1.7143.
I have similar lines of jooq code which use SUM as opposed to COUNT and they return a value to 4 decimal places but I cannot find a way to get the above code to return the value to 4 decimal places.
I have tried using .round but had no success.
Has anyone else had a similar problem and knows of a solution?
There are two issues here, depending on what RDBMS you're using:
1. The type of the whole projected expression
The type of the whole division expression depends on the type of the left hand side (dividend), which is SQLDataType.INTEGER. So, irrespective of whether your RDBMS returns a decimal or floating point number, jOOQ will use JDBC's ResultSet.getInt() method to fetch the value, where you will be losing precision. So, the first step is to make sure jOOQ will fetch the desired data type. There are several ways to do this:
Use a cast on the COUNT(*) expression: count(MYTABLE.ID).cast(SQLDataType.DOUBLE).divide(7)
Use a cast on the entire expression:
count(MYTABLE.ID).divide(7).cast(SQLDataType.DOUBLE)
Use data type coercion on either expression: expr.coerce(SQLDataType.DOUBLE)
Casts have an effect on the generated SQL. Data type coercions do not.
2. How your RDBMS handles data types
In most RDBMS, count(*) expressions produce an integer type, and your division's right hand side (divisor) is also an integer, so the best resulting data type is, in fact, an integer type. I suspect you should pass a double or BigDecimal type as your divisor instead.
Solution
The ideal solution would then be to combine the above two:
dsl.select(count(MYTABLE.ID).cast(SQLDataType.DOUBLE).divide(7.0))
.from(MYTABLE)
.fetch();

what is the different betwen "equalTo" and "startAt & endAt" in firebase and when i should use "equalTo" or "startAt and endAt"?

I have been using two codes below when i'm trying to find record by email or phone number, sometimes first code working fine sometimes not working and also the second code same too.
what is the difference between codes below and when i should use "equalTo" or "startAt and endAt"?
ref.orderByChild("email")
.equalTo(str)
and
ref.orderByChild("email")
.startAt(str)
.endAt(str+"\\uf8ff")
ref.orderByChild("email").equalTo(str)
The above means that the email has to be equal to the value of str. It is the same as saying WHERE email= 'userx#gmail.com'
ref.orderByChild("email").startAt(str).endAt(str+"\\uf8ff")
This is like saying WHERE email LIKE ca% which will return all emails that start with "ca"
public Query startAt (String value)
Create a query constrained to only return child nodes with a value greater than or equal to the given value, using the given orderBy directive or priority as default.
public Query endAt (String value)
Create a query constrained to only return child nodes with a value less than or equal to the given value, using the given orderBy directive or priority as default.
The \uf8ff is simply the last character in unicode, so acts as an end guard.
Check this for queries:
https://www.youtube.com/watch?v=sKFLI5FOOHs
It's true that in "some" cases, you can achieve the same thing using either the first approach or either the other but from the official documentation regarding filtering data, each method has a difference purpose as:
equalTo() - Return items equal to the specified key or value depending on the order-by method chosen.
startAt() - Return items greater than or equal to the specified key or value depending on the order-by method chosen.
endAt() - Return items less than or equal to the specified key or value depending on the order-by method chosen.
But as a conclusion, use the first approach when you want to have a perfect match. The second approach is used usually for a search query when you want to filter data that starts with some characters. In terms of SQL, note that there isn't an equivalent to LIKE clause in Firebase but with the second approach we simulate the exact same behaviour.

Postgres data type cast

My database is Postgres 8. I need to cast data type to another. That means, one of columns data type is varchar and need to cast it into int with Postgres in a SELECT statement.
Currently, I get the string value and cast it into int in Java.
Is there any way to do it? Sample code would be highly appreciated.
cast(varchar_col AS int) -- SQL standard
or
varchar_col::int -- Postgres syntax shorthand
Theses syntax variants are valid (almost) anywhere. The second may require nesting parentheses in special situations:
PostgreSQL: Create index on length of all table fields
And the first may be required where only functional notation is allowed by syntax restrictions:
PostgreSQL - CAST vs :: operator on LATERAL table function
There are two more variants:
int4(varchar_col) -- only works for some type names
int '123' -- must be an untyped, quoted string literal
Note how I wrote int4(varchar_col). That's the internal type name and there is also a function defined for it. Wouldn't work as integer() or int().
Note also that the last form does not work for array types. int[] '{1,2,3}' has to be '{1,2,3}'::int[] or cast('{1,2,3}' AS int[]).
Details in the manual here and here.
To be valid for integer, the string must be comprised of an optional leading sign (+/-) followed by digits only. Leading / trailing white space is ignored.

How to perform a Restrictions.like on an integer field

I have an integer field in the DB (Postgresql) and my hibernate mapping file that I want to use in a like operation (e.g. Restrictions.like(Bean.fieldname,'123')).
The database does not support like for integer without explicit type casting select * from table where text(myint) like '1%'. Ideally, I'd like to keep the DB field type and Hibernate property type as integers and not have to load all the fields from the DB to iterate through in the Java code.
cheers :)
If the value really is a number, I'd just restrict it to a range - e.g. greater than or equal to 100 and less than 200. I wouldn't have thought you'd really want "all numbers starting with 1" - that suggests that 1 and 10000 are similar, whereas 1 and 2 are totally different. The information in a number should almost always relate to its magnitude, not the digits from its decimal representation.
Why do you need a LIKE? It's a very strange comparison, that's also why it's not an integer operator.
You could cast the value in the database to text/varchar, but you will kill performance unless you create a special index as well.
Restrictions.sqlRestriction("CAST({alias}.myint AS CHAR) like ?", "%1%", Hibernate.STRING));

No operator matches the given name and argument type(s). You might need to add explicit type casts. -- Netbeans, Postgresql 8.4 and Glassfish

I am trying to edit a table in Postgresql using JPA in Glassfish using EclipseLink. When I insert an entity, it runs fine. But, when I try to edit or remove the same entity, it fails with the following error. Any idea?
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: operator does not exist: integer = character varying
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Position: 38
Error Code: 0
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1422)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:799)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:867)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:587)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:530)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeCall(AbstractSession.java:914)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:205)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:191)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.deleteObject(DatasourceCallQueryMechanism.java:182)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:101)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeDatabaseQuery(DeleteObjectQuery.java:167)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:675)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:589)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:109)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:112)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:86)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2857)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1225)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1207)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1167)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:297)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:256)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1406)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:547)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1508)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3128)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:268)
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:157)
at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:412)
... 25 more
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: integer = character varying
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Position: 38
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:321)
at com.sun.gjc.spi.base.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:108)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:792)
... 53 more
Java Result: 1
I had this issue, and solved. This was due to the WHERE clause contains String value instead of integer value.
This the main error:
ERROR: operator does not exist:
integer = character varying
You code is trying to match an integer and a string, that's not going to work. Fix your code, get the query that is involved to see if you fixed it. See also the PostgreSQL log files.
A workaround (NOT A SOLUTION!) is to do some casting. Check this article.
This is due to the mismatch column type to the Java entity data type. In query where you are passing query parameters, typecast parameter to an integer
e.g. in the case of PostgreSQL, it might be
where table_name.column_name_with_integer_type = (:named_parameter_of_character_type)::integer
::integer will convert the parameter value into an integer.
Doesn't look like you got an answer but this problem can also creep up if you're passing null ID's into your JPA Predicate.
For instance.
If I did a query on Cats to get back a list. Which returns 3 results.
List catList;
I then iterate over that List of cats and store a foriegn key of cat perhaps leashTypeId in another list.
List<Integer> leashTypeIds= new ArrayList<>();
for(Cats c : catList){
leashTypeIds.add(c.getLeashTypeId);
}
jpaController().findLeashes(leashTypeIds);
If any of the Cats in catList have a null leashTypeId it will throw this error when you try to query your DB.
(Just realized I am posting on a 5 year old thread, perhaps someone will find this useful)
This is due to the mismatch of the data type of your java Entity and the database table column.
Please review if all the column is exact same data type as your entity.
This mismatch happens when we update our model attribute's data-type.
Bro, I had the same problem. Thing is I built a query builder, quite an complex one that build his predicates dynamically pending on what parameters had been set and cached the queries. Anyways, before I built my query builder, I had a non object oriented procedural code build the same thing (except of course he didn't cache queries and use parameters) that worked flawless. Now when my builder tried to do the very same thing, my PostgreSQL threw this fucked up error that you received too. I examined my generated SQL code and found no errors. Strange indeed.
My search soon proved that it was one particular predicate in the WHERE clause that caused this error. Yet this predicate was built by code that looked like, well almost, exactly as how the procedural code looked like before this exception started to appear out of nowhere.
But I saw one thing I had done differently in my builder as opposed to what the procedural code did previously. It was the order of the predicates he put in the WHERE clause! So I started to move this predicate around and soon discovered that indeed the order of predicates had much to say. If I had this predicate all alone, my query worked (but returned an erroneous result-match of course), if I put him with just one or the other predicate it worked sometimes, didn't work other times. Moreover, mimicking the previous order of the procedural code didn't work either. What finally worked was to put this demonic predicate at the start of my WHERE clause, as the first predicate added! So again if I haven't made myself clear, the order my predicates where added to the WHERE method/clause was creating this exception.
I guess this can be due to many things.
In my case it was having "WHERE id IN" condition in my query and I was setting IDs separated by dash as a string using setString method on PreparedStatement.
Not sure if there is better way to do this but I just added placeholder in my statement and replaced it by values on my own.
In my case, I used a keyword as a column name, which resulted in ERROR: operator does not exist: name = bigint
The solution was to use double quotes around the column name.
I had this issue in a very simple DELETE statement, and it is now solved.
My issue was due to using backticks around the column (this column was named "id").
This query DID NOT WORK and resulted in "No operator matches the given name and argument type(s)"
DELETE FROM mytable WHERE `id` = 3 -- DO NOT USE BACKTICKS
Coming from mysql, in dynamic queries, I always `backtick` columns.
The following query DID WORK (with backticks removed):
DELETE FROM mytable WHERE id = 3
I had this problem when i was trying to query by passing a Set and i didn't used In
example
problem : repository.findBySomeSetOfData(setOfData);
solution : repository.findBySomeSetOfDataIn(setOfData);
If anyone is having this exception and is building the query using Scala multi-line strings:
Looks like there is a problem with some JPA drivers in this situation. I'm not sure what is the character Scala uses for LINE END, but when you have a parameter right at the end of the line, the LINE END character seems to be attached to the parameter and so when the driver parses the query, this error comes up. A simple work around is to leave an empty space right after the param at the end:
SELECT * FROM some_table a
WHERE a.col = ?param
AND a.col2 = ?param2
So, just make sure to leave an empty space after param (and param2, if you have a line break there).
If you are using Primefaces, you should insert inside the the .xhtml file so it converts correctly to java integer. For example:
<p:selectCheckboxMenu
id="frameSelect"
widgetVar="frameSelectBox"
filter="true"
filterMatchMode="contains"
label="#{messages['frame']}"
value="#{platform.frameBean.selectedFramesTypesList}"
converter="javax.faces.Integer">
<f:selectItems
value="#{platform.frameBean.framesTypesList}"
var="area"
itemLabel="#{area}"
itemValue="#{area}" />
</p:selectCheckboxMenu>
Here is what you can do to fix it in PostgreSQL:
ALTER TABLE schema_name."table_name"
ALTER COLUMN "column_name" TYPE integer USING(same_column_name_again::INTEGER);
By doing this, you will change the column data type, fixing the issue of mismatch between column type to the Java entity data type.

Categories