Optional where condition with List input variable - postgresql

I'm trying to ignore condition when the input is null. There are already a lot of threads on stackoverflow dealing with this situation but I've not been able to find one with a List input variable.
The mentionned solution does not work as IN null raises an error. That's why I added a COALESCE :
:toto type : List<Integer>
SELECT *
FROM test_table
WHERE (:toto is null OR year IN (COALESCE(:toto, (1, 2))))
Problem is that COALESCE itself returns an error :
COALESCE types bytea and record cannot be matched
Strangest thing is that this query is working with a null input if I'm making a raw query directly onto the database. I'm suspecting JPA to don't give a real null value to :toto.
Any solution leading to make index working and providing the correct behavior would be ok.

Related

SQL `NULL` read at column 1 (JDBC type null) but mapping is to a non-Option type

I want select the max value using this query (all fields in table are not null):
dc.run(quote {
query[SchemaInfo]
.filter(_.subjectName == lift(subject))
.map(_.version)
.max
}).map(_.map(_ + 1).getOrElse(1))
I know, that table may be empty, so i use this: map(_.map(_ + 1).getOrElse(1)).
The problem is that this query produces this error:
SQL NULL read at column 1 (JDBC type null) but mapping is to a
non-Option type; use Option here. Note that JDBC column indexing is
1-based.
doobie.util.invariant$NonNullableColumnRead: SQL NULL read
at column 1 (JDBC type null) but mapping is to a non-Option type; use
Option here. Note that JDBC column indexing is 1-based.
How to fix it?
Without quill (using pure doobie) the same query working correctly
I know that you probably got the answer already, but I will leave my comment here so that it hopefully help someone in the future.
so the problem is in line
query[SchemaInfo]
as the record may not exist it should be mapped into
query[Option[SchemaInfo]].unique

Postgres COALESCE inside nullif for 2 different fields

I am new to SQL and POSTGRES and had a quick question. Right now I have 2 different tables one with car info and one with partial car info and I would like to sort on car.vin OR partial_car.vin depending if either exists and sending all nulls/empty strings to the end of the sort. Currently my ORDER BY statement looks like:
ORDER BY nullif(coalesce(car.vin, partial_car.partial_vin), '') asc nulls last limit 50 offset 0
My expectation for this is that coalesce will take the first non null value and use that for sorting or it will return null and send that to the end. My results so far I haven't been able to make sense of. There are null values being placed in between actual values etc.. If I make this change coalesce(car.vin, '') again I see it work properly. Anyone have an ideas as to why this is the behavior? Let me know if you need something more from me.
It was human error on my end. The object being sent to client was not being populated properly with partial data. So sorting was correct but was seeing blanks due to those values not being present.

PostgreSql Queries treats Int as string datatypes

I store the following rows in my table ('DataScreen') under a JSONB column ('Results')
{"Id":11,"Product":"Google Chrome","Handle":3091,"Description":"Google Chrome"}
{"Id":111,"Product":"Microsoft Sql","Handle":3092,"Description":"Microsoft Sql"}
{"Id":22,"Product":"Microsoft OneNote","Handle":3093,"Description":"Microsoft OneNote"}
{"Id":222,"Product":"Microsoft OneDrive","Handle":3094,"Description":"Microsoft OneDrive"}
Here, In this JSON objects "Id" amd "Handle" are integer properties and other being string properties.
When I query my table like below
Select Results->>'Id' From DataScreen
order by Results->>'Id' ASC
I get the improper results because PostgreSql treats everything as a text column and hence does the ordering according to the text, and not as integer.
Hence it gives the result as
11,111,22,222
instead of
11,22,111,222.
I don't want to use explicit casting to retrieve like below
Select Results->>'Id' From DataScreen order by CAST(Results->>'Id' AS INT) ASC
because I will not be sure of the datatype of the column due to the fact that JSON structure will be dynamic and the keys and values may change next time. and Hence could happen the same with another JSON that has Integer and string keys.
I want something so that Integers in Json structure of JSONB column are treated as integers only and not as texts (string).
How do I write my query so that Id And Handle are retrieved as Integer Values and not as strings , without explicit casting?
I think your assumtions about the id field don't make sense. You said,
(a) Either id contains integers only or
(b) it contains strings and integers.
I'd say,
If (a) then numerical ordering is correct.
If (b) then lexical ordering is correct.
But if (a) for some time and then (b) then the correct order changes, too. And that doesn't make sense. Imagine:
For the current database you expect the order 11,22,111,222. Then you add a row
{"Id":"aa","Product":"Microsoft OneDrive","Handle":3095,"Description":"Microsoft OneDrive"}
and suddenly the correct order of the other rows changes to 11,111,22,222,aa. That sudden change is what bothers me.
So I would either expect a lexical ordering ab intio, or restrict my id field to integers and use explicit casting.
Every other option I can think of is just not practical. You could, for example, create a custom < and > implementation for your id field which results in 11,111,22,222,aa. ("Order all integers by numerical value and all strings by lexical order and put all integers before the strings").
But that is a lot of work (it involves a custom data type, a custom cast function and a custom operator function) and yields some counterintuitive results, e.g. 11,111,22,222,0a,1a,2a,aa (note the position of 0a and so on. They come after 222).
Hope, that helps ;)
If Id always integer you can cast it in select part and just use ORDER BY 1:
select (Results->>'Id')::int From DataScreen order by 1 ASC

OrientDB COALESCE Function With Unexpected Results

Using OrientDB 2.1.2, I was trying to use the inherent COALESCE functionality and ran into some strange results.
Goal: select the maximum value of a property based on certain conditions OR 0 if there is no value for that property given the conditions.
Here's what I tried to use to produce my results.
Attempt 1: Just selecting the Maximum value of a property based on some condition - This worked as I expected... a single result
Attempt 2: Same query as before but now I'm adding an extra condition that I know will cause no results to be returned - This also worked as I expected... no results found
Attempt 3: Using COALESCE to select 0 if the result from the second query returns no results - This is where the query fails (see below).
I would expect the result from the second query to return no results, thereby qualifying as a "NULL" result meaning that the COALESCE function should then go on to return 0. What happens instead is that the COALESCE function is seeing the results of the inner select (which again, returns no results) as a valid non-null value, causing the COALESCE function to never return the intended "0" value.
Two questions for those who are familiar with using the OrientDB API:
Do you think this functionality is working properly or should an issue be filed with the orientdb issue tracker?
Is there another way to achieve my goal without using COALESCE or by using COALESCE in a different way?
Try rather:
select coalesce($a, 0) from ... let $a = (subquery) where ...
Or also this variant because the sub-select returns a result set, but the coalescence wants a single value:
select coalesce($a[0], 0) from ... let $a = (subquery) where ...

Null checking in ireport

I my web application I am using I-REPORT designer for designing report.
For the data used in report,I have written a query that fetch two column values from different table.Here data type of column data is real.In ireport corresponding data type is Float.
Here,if one of the data have a value,other have a no value or empty.So I have to display a value that is not null or empty using text field,when the report is generated.So I have implemented condition in text field
( $F{permit_quantity}==null ?$F{fst_insp_qpqlml_quantity} : $F{permit_quantity} )
Here the fields $F{permit_quantity}, $F{fst_insp_qpqlml_quantity} corresponding to two column values returned by query.
But the above condition is not working when $F{permit_quantity} is empty or null.
I am using postgresql database
You can try to use .equals() Method if the condition itself is not working.
$F{permit_quantity}.equals(null) ? $F{fst_insp_qpqlml_quantity} : $F{permit_quantity}
There could be various other reasons why your code doesn´t work but I can´t tell from your snippet.
$F{permit_quantity}.toString() == null ? $F{fst_insp_qpqlml_quantity} :
$F{permit_quantity}
This solves your problem.