How does implicit casting work in Oracle NoSQL Database? - nosql

I am trying to understand the implicit cast behavior.
I have a column called ticketNo, this is a string and it is a pk.
Using the same datatype in both sides, I am returning one row
SELECT * FROM demo d WHERE ticketNo = "1762386738153"
When I am doing a explicit cast, this query is returning the same row
SELECT * FROM demo d WHERE cast (ticketNo as Long)= 1762386738153
Now, when I am doing an implicit cast, this query is returning no rows
SELECT * FROM demo d WHERE ticketNo = 1762386738153
Any ideas ?

There is no implicit cast behavior in Oracle NoSQL Database. String types are not comparable to Long types so the predicate ticketNo = 1762386738153 returns always false in your case. A string item is comparable to another string item. A string item is also comparable to an enum item.
In your case, this is your primary key, in order to have the best performances, it is not recommended to do a CAST. Validate the types before do this query. A primary key is always typed, no wildcard or complex types are accepted
Otherwise,
the reason for returning false for incomparable items, instead of
raising an error, is to handle truly schemaless applications, where
different table rows may contain very different data or differently
shaped data. As a result, even the writer of the query may not know
what kind of items an operand may return and an operand may indeed
return different kinds of items from different rows.
you can always execute the explicit CAST operation when needed, as you did.
If you are interested in have more information : https://docs.oracle.com/en/database/other-databases/nosql-database/20.3/sqlreferencefornosql/value-comparison-operators.html

Related

How to understand the return type?

I'm building a framework for rust-postgres.
I need to know what value type will be returned from a row.try_get, to get the value in a variable of the appropriate type.
I can get the sql type from row.columns()[index].type, but not if the value is nullable , so i can't decide to put the value in a normal type or a Option<T>.
I can use just the content of the row to understand it, i can't do things like "get the table structure from Postgresql".
is there a way?
The reason that the Column type does not expose any way to find out if a result column is nullable is because the database does not return this information.
Remember that result columns are derived from running a query, and that query may contain arbitrary expressions. If the query was a simple SELECT of columns from a table, then it would be reasonably simple to determine if a column could be nullable.
But it could also be a very complex expression, derived from multiple columns, subselects or even custom functions. Postgres can figure out the data type of each column, but in the general case it doesn't know if a result column may contain nulls.
If your application is only performing simple queries, and you know which table column each result column comes from, then you can find out if that table column is nullable like this:
SELECT is_nullable
FROM information_schema.columns
WHERE table_schema='myschema'
AND table_name='mytable'
AND column_name='mycolumn';
If your queries are not that simple then I recommend you always get the result as an Option<T> and handle the possibility that the result might be None.

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

Postgresql 9.1 enum type ordering doesn't work like I expect

I've got an enum type that I've become interested in ordering in a particular way. I've written and run the SQL to impose a new ordering by sorting the labels (externally) by my new criteria and then updating the enumsortorder for all the values.
It doesn't work. I've verified that I've satisfied the (really weird) rule that the sort ordering feature works only on enum types with even oids; my oid for this type is even (58016). As far as I can tell, the ordering being imposed when I ORDER BY the enum column is exactly the same as what it was before.
Is there something else I need to do in order to make this work? The PostgreSQL documentation makes me think it should work.
Even oids have fixed ordering so you can't reorder them by modifying the pg-enum system table.
you're going to have to replace the existing enum with a new enum type. this means
Creating a new enum type
Dropping any relationships that use the enum.
Update the columns to the new type using something like
ALTER TABLE foo ALTER COLUMN bar
TYPE TO new_enum_type
USING (bar::text)::new_enum_type;
Here the cast to text matches the new enum values to the old enum values by their name.
Finally you need to recreate all the dropped relationships.
If needed you can run all this DML inside a transaction block.
Expect it to be slow if you have lots of data as it's rewriting whole
tables

IBM DB2 9.7, any difference between inlined CLOB and VARCHAR?

Using IBM DB2 9.7, in a 32k tablespace, assuming a 10000b (ten thousand bytes) long column fits nicely in a tablespce. Is there a difference between these two, and is one preferred over the other?
VARCHAR(10000)
CLOB(536870912) INLINE LENGTH 10000
Is either or preferred in terms of functionality and performance? A quick look at the two would be that the CLOB is actually more versatile; all content shorter than 10000 is stored in stablespace, but IF bigger content is required then that is fine too, it is just stored elsewhere on disk.
There are a number of restrictions on the way CLOB can be used in a query:
Special restrictions apply to expressions resulting in a CLOB data
type, and to structured type columns; such expressions and columns are
not permitted in:
A SELECT list preceded by the DISTINCT clause
A GROUP BY clause An ORDER BY clause A subselect of a set operator other
than UNION ALL
A basic, quantified, BETWEEN, or IN predicate
An aggregate function
VARGRAPHIC, TRANSLATE, and datetime scalar functions
The pattern operand in a LIKE predicate, or the search
string operand in a POSSTR function
The string representation of a
datetime value.
So if you need to do any of those things, VARCHAR is to be preferred.
I don't have a definitive answer about performance (unfortunately, information like this just doesn't seem to be in the documentation--or at least, it is not easily locatable). However, logically speaking, the DB has more work to do with a CLOB. It has to decide whether to return the CLOB directly in the result or not. That has to mean at least some overhead. Here is a good discussion of some of the issues, though it doesn't give a clear answer on performance, either.
My default position would be to use VARCHAR unless CLOB is really needed (data in the column can be bigger than the VARCHAR limit).

SOQL Type conversion (SalesForce.com)

The problem is that I need to compare two fields of different types in a SOQL query.
TextField is a Picklist (so really text) and IntField is a Number(2, 0). Changing the types of these fields is not possible.
I would like to write SOQL like;
SELECT Id FROM SomeObject__c
WHERE Cast(TextField as Integer) > IntField
Obviously Cast(TextField as Integer) does NOT work.
Any advise on type conversion within SOQL. The normal APEX functions (e.g. integer.valueof) don't seem to be of any help here.
Thanks
SOQL itself does not support casting but you can always lend a helping hand ;)
Create a Numeric formula field in SomeObject__c:
IF(ISNUMBER(TextField__c), VALUE(TextField__c), NULL)
or something similar depending on your definition of cast to int. Now you can use this field in a SOQL query.