Create postgresql index on text column casted to array - arrays

I have a postgresql table that has a column with data type = 'text' in which I need to create an index which involves this column being type casted to integer[]. However, whenever I try to do so, I get the following error:
ERROR: functions in index expression must be marked IMMUTABLE
Here is the code:
create table test (a integer[], b text);
insert into test values ('{10,20,30}','{40,50,60}');
CREATE INDEX index_test on test USING GIN (( b::integer[] ));
Note that one potential workaround is to create a function that is marked as IMMUTABLE that takes in a column value and performs the type casting within the function, but the problem (aside from adding overhead) is that I have many different 'target' array data types (EG: text[], int2[], int4[], etc...), and it would not be possible to create a separate function for each potential target array data type.

Answered in this thread on the PostgreSQL mailing lists. Click on "Follow-ups" or "next by thread" in the links after the post to follow the (short) thread on the topic.
There's no recipe given there, but Tom's just talking about defining an explicit cast from text[] to integer[]. If time permits I'll flesh this answer out with an example.

Related

Adding all table fields into the SE11 structure?

I'm learning SAP and ABAP language, I need to create a structure with all the fields of the SFLIGHT database table and a few more. Do I have to enter all the fields of the SFLIGHT table manually or is there any possibility to add all the fields of a given table at once?
I have to create DDIC structure like that:
Do I have to fill this component names manually?
The code solution is given by Jonas, but if you are asking about SE11-way then
Edit => scroll down to Include => click on Insert
https://techazmaan.com/ddic-include-structure/
With the TYPES ... LINE OF statement one can declare a type which represents a structure for one line of a table:
TYPES flight TYPE LINE OF sflight.
" the structure type can then be used in the program
DATA(scheduled_flight) = VALUE flight(
" ...
).
INSERT scheduled_flight INTO sflight.
Thus usually there is no need to declare such a structure in the dictionary, as it already exists implicitly through the table creation.

How to index a dataframe with a user-defined string?

Assumptions: I have a Julia DataFrame with a column titled article_id.
Normally, I can declare a DataFrame using some syntax like df = DataFrame(CSV.File(dataFileName; delim = ",")). If I wanted to get the column pertaining to a known attribute, I could do something like df.article_id. I could also index that specific column by doing df."article_id".
However, if I created a string and assigned it to the value of article_id, such as str = "article_id", I cannot index the dataframe via df.str: I get an error by doing so. This makes sense, as str is not an attribute of the DataFrame, yet the value of str is an attribute of the DataFrame. How can I index the DataFrame to get the column corresponding to the value of str? I'm looking for some syntax similar to df.valueof(str).
Are there any solutions to this?
From the DataFrames.jl manual's "Getting started" page:
Columns can be directly (i.e. without copying) accessed via df.col, df."col", df[!, :col] or df[!, "col"]. The two latter syntaxes are more flexible as they allow passing a variable holding the name of the column, and not only a literal name.
So you can write df[!, str], and that will be equivalent to df.article_id if str == "article_id".
The Indexing section of the manual goes into even more detail, for when you need more advanced types of indexing or want a deeper understanding of the options.
For an additional reference. When you write:
df.colname
it is equivalent to writing getproperty(df, :colname). Therefore if you have column name stored in the str variable you can write getproperty(df, str).
However, as Sundar R noted it is usually more convenient to use indexing instead of property access. Two most common patterns are df[!, str] which is equivalent to getproperty(df, str) and gets you a column without copying it and df[:, str] which gets you a copy of a column.

checking structure of GLobally defined Varray or nested table in PL/SQL

I am modifying a package. In one of the procedure I got below line.
query_det_arr ecc_query_det_arr_type := ecc_query_det_arr_type(NULL);
this ecc_query_det_arr_type is not defined anywhere inside the package. as per my understanding this must be varray or nested table.
They may have created using separate create command.
Is there anyway to check what ecc_query_det_arr_type contains? I mean any query or anyway in sql developer?
One way to do that is desc <your_type> like below:
desc ecc_query_det_arr_type;
A side note: Since you are taking a guess here, I thought of writing. It is always better to follow a naming convention for Oracle Objects. In your case I would have created that type like below:
ecc_query_det_ntt if it is nested table type
ecc_query_det_aat if it is associative array type
ecc_query_det_vat if it is varray type
Ok, here is another way:
select * from user_source where type = 'TYPE' and lower(name) = 'ecc_query_det_arr_type';

Columnarization for "non-native" data types loaded into VARIANT column

In the documentation there is a section on semi-structured considerations that warns against certain situations in which values for a given path in a VARIANT column will not be materialized; for example, if the values do not all have the same data type. That is, if both {"foo":1} and {"foo":"1"} are present, the value for "foo" obviously cannot be extracted as its column.
But in the case where all values have the same type, it's still not entirely clear how so-called non-native types are handled.
The documentation describes for example dates and timestamps as non-native in the context of the VARIANT data type (meaning that such values are "stored as strings"), my question is whether this extends to number types such as FLOAT8. The documentation suggests that native types might be understood in the context of JSON (which has a native number type that is rather hybrid in nature).
Is FLOAT8 a native type in VARIANT data or is it stored as a string?
Would such a value (stored as a string) be extracted into its own column or appear as a "parsed semi-structured structure" along with those remaining values that weren't extracted into other columns?
The documentation suggests that one makes performance tests "to see which structure provides the best performance" but this would be a lot easier with an accurate understanding of the extraction logic.
The following test suggests that yes FLOAT8 is not stored as a string, so I expect it to be stored in a way where it can be retrieved(/pruned etc) independently of the other data in the JSON during query execution.
create table foo (col variant) as (select object_construct('x', FLOOR(random()*1000000)::float8) col from table(generator(rowcount => 100000000)));
create table foo2 (col variant) as (select object_construct('x', col:x::string) col from foo);
TABLE_NAME BYTES
FOO 800071680
FOO2 1480282112

How to compare numeric in PostgreSQL JSONB

I ran into strange situation working with jsonb type.
Expected behavior
Using short jsonb structure:
{"price": 99.99}
I wrote query like this:
SELECT * FROM table t WHERE t.data->price > 90.90
And it fail with error operator does not exist: jsonb > numeric the same as text (->>) operator does not exist: text > numeric
Then I wrote comparison as mentioned in many resources:
SELECT * FROM table t WHERE (t.data->>price)::NUMERIC > 90.90
And it's works as expected.
What's strange:
SELECT * FROM table t WHERE t.data->price > '90.90';
a little weird but query above works right.
EXPLAIN: Filter: ((data -> 'price'::text) > '90.90'::jsonb)
But if I change jsonb value to text as: {"price": "99.99"}
there is no result any more - empty.
Question: How actually PostgreSQL compare numeric data and what preferable way to do this kind of comparison.
But you aren't comparing numeric data, are you.
I can see that you think price contains a number, but it doesn't. It contains a JSON value. That might be a number, or it might be text, or an array, or an object, or an object containing arrays of objects containing...
You might say "but the key is called 'price' of course it is a number" but that's no use to PostgreSQL, particularly if I come along and sneakily insert an object containing arrays of objects containing...1
So - if you want a number to compare to you need convert it to a number (t.data->>price)::NUMERIC or convert your target value to JSON and let PostgreSQL do a JSON-based comparison (which might do what you want, it might not - I don't know what the exact rules are for JSON).
1 And that's exactly the sort of thing I would do, even though it is Christmas. I'm a bad person.

Resources