Postgresql: why "ILIKE" is case-sensitive sometimes? - postgresql

I'm searching this row:
"c717e4d6-8db3-4c68-8c6f-f853c6c62312", "Аристотель", "source"
These queries successfully finding it:
SELECT id, name, type FROM amt WHERE owner = '802f11da-c41c-4ad0-ae15-c7cf734c807f' AND name LIKE '%Ари%' limit 5;
SELECT id, name, type FROM amt WHERE owner = '802f11da-c41c-4ad0-ae15-c7cf734c807f' AND name ILIKE '%Ари%' limit 5;
This one does NOT finding it:
SELECT id, name, type FROM amt WHERE owner = '802f11da-c41c-4ad0-ae15-c7cf734c807f' AND name ILIKE '%ари%' limit 5;
As you see, the difference between 2nd and 3rd query is only one letter: "Ари" vs "ари".
Usually, ILIKE works as expected, but in some cases it just can't properly search. I have no idea why it happens.
SQL pane from current database:
CREATE DATABASE v_2_prod
WITH OWNER = postgres
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'C'
LC_CTYPE = 'C'
CONNECTION LIMIT = -1;

Related

Oracle query to Postgress query change ERROR

We are in progress to move our db to Postgres from Orcale.
There is this Oracle query (changed verbiage for privacy concerns):
SELECT * FROM (SELECT somedata.* FROM SNSN.SMS_TXN_SOMEDATA somedata
WHERE ((car= 'tesla' OR car = 'teslaX' OR car = 'teslaY') OR (buyer= 'john' OR buyer = 'rony' OR jim = 'sam'))
AND code = :code
ORDER BY somedata.datetime)
WHERE LIMIT :num
When I hit the endpoint I get this error
ERROR: argument of LIMIT must be type bigint, not type character varying
What would be a suitable/alternative variable to bind this. What can I use instead of variables :code and :num.

Tracking SQL functions in Hasura

Basically I'm trying to compare two JSONB rows and return a numeric value. But I wanna be able to query for it. I'm not sure whether I should use a custom SQL function, a calculated field, or a Postgres generated column, so I need a bit of advice.
I have a jsonb column for each user that keeps a few hundreds of keys/values as such:
USERS TABLE:
| username | user_jsonb_column |
|-----------------------------------------------------------|
| 'user1' | {"key1":"value1", "key2":"value2" ... } |
|--------------|--------------------------------------------|
| 'user2' | {"key2":"value2", "key3":"value3" ... } |
I am trying to calculate the similarity of the jsonb rows of 2 users with a very simple SQL query as such:
SELECT ROUND ((
SELECT COUNT(*) from (
SELECT jsonb_each(user_jsonb_column)
FROM users WHERE username = 'johndoe'
INTERSECT
SELECT jsonb_each(user_jsonb_column)
FROM users WHERE username = 'janedoe'
)::decimal AS SAME_PAIRS
/ --divide it by
SELECT COUNT(*) from (
SELECT jsonb_object_keys(user_jsonb_column)
FROM users WHERE username = 'johndoe'
INTERSECT
SELECT jsonb_object_keys(user_jsonb_column)
FROM users WHERE username = 'janedoe'
) as SAME_KEYS
) * 100) as similarity_percentage
This is working as intended and gives me the similarity result between 2 json objects as a percentage.
I am trying to turn this into a function so that I can query for the similarity percentage of 2 users as such:
query {
calculate_similarity_percentage(
args: {user1: "johndoe", user2: "janedoe"}
){
similarity_percentage_value
}
}
But I'm stuck at this point because I'm not sure whether I should think in terms of a trackable custom SQL function (which should return SETOF <TABLE> but I need a numeric value), a computed field (which can also return BASE type), or maybe a Postgres generated column in my situation.
I've been reading https://hasura.io/docs/1.0/graphql/core/schema/custom-functions.html and https://hasura.io/docs/1.0/graphql/core/schema/computed-fields.html but I couldn't quite figure out how to approach this, so any kind of help or comment would be appreciated.
Update: Yes, as Laurenz Albe pointed out, I am able to create a function like this:
CREATE OR REPLACE FUNCTION public.calculate_similarity_percentage(text, text)
RETURNS numeric
LANGUAGE sql
STABLE
AS $function$
SELECT ROUND(
(select count(*) from (
SELECT jsonb_each(user_jsonb_column) FROM users WHERE username = $1
INTERSECT
SELECT jsonb_each(user_jsonb_column) FROM users WHERE username = $2
) as SAME_PAIRS
)::decimal / (
select count(*) from (
SELECT jsonb_object_keys(user_jsonb_column) FROM users WHERE username = $1
INTERSECT
SELECT jsonb_object_keys(user_jsonb_column) FROM users WHERE username = $2
) as SAME_KEYS
)
* 100) as similarity_percentage
$function$
Then I can execute this function:
SELECT calculate_similarity_percentage('johndoe','janedoe')
And it returns this without any problem:
similarity_percentage
62
However, I would like Hasura to track this function so that I can query it on graphQL as:
query MyQuery {
calculate_similarity_percentage(args: {user1: "johndoe", user2: "janedoe"}) {
similarity_percentage
}
}
But if I try to track the function above, Hasura says:
**SQL Execution Failed**
in function "calculate_similarity_percentage":
the function "calculate_similarity_percentage" cannot be tracked for the following reasons:
• the function does not return a "COMPOSITE" type
• the function does not return a SETOF
• the function does not return a SETOF table
I have no idea if I can find a workaround and return a numeric value as a "COMPOSITE" or SETOF table.
Here is how I kind of solved my case. But this was not the optimal solution so I'm not accepting this as an answer.
I ended up creating another table like this:
USER_RELATION_TABLE:
| user1_col | user2_col |
|--------------------------|
| 'johndoe' | 'janedoe' |
|--------------------------|
| 'brad' | 'angelina' |
|--------------------------|
| ... | ... |
Then I added a computed field on the relation table with the following function:
CREATE OR REPLACE FUNCTION public.calculate_similarity_percentage(user_relation_row user_relation_table)
RETURNS numeric
LANGUAGE sql
STABLE
AS $function$
SELECT ROUND(
(select count(*) from (
SELECT jsonb_each(user_jsonb_column) FROM users
WHERE username = user_relation_row.user1_col
INTERSECT
SELECT jsonb_each(user_jsonb_column) FROM users
WHERE username = user_relation_row.user2_col
) as SAME_PAIRS
)::decimal / (
select count(*) from (
SELECT jsonb_object_keys(user_jsonb_column) FROM users
WHERE username = user_relation_row.user1_col
INTERSECT
SELECT jsonb_object_keys(user_jsonb_column) FROM users
WHERE username = user_relation_row.user2_col
) as SAME_KEYS
)
* 100) as similarity_percentage
$function$
Now I can query it on the graphQL like this:
query MyQuery {
user_relation_table {
similarity
}
}

query error: no field 'face' found in schema

i have bigint column named as face in mysql. and this is my sphinx.conf
source src1
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass = pass
sql_db = nums
sql_port = 3306 # optional, default is 3306
sql_query = SELECT id,id AS id_attr,tel,name,sex,face from tel
sql_attr_uint = id_attr
sql_attr_bigint = face
}
index num
{
rt_attr_bigint = face
rt_field = face
source = src1
path = C:/sphinx/bin/data/numaralar
}
i can make search by name and tel but not with face.
Fatal error: Uncaught exception 'Foolz\SphinxQL\Exception\DatabaseException' with message '[1064] index nums: query error: no field 'face' found in schema [ SELECT * FROM nums WHERE MATCH('(#face 123456)') LIMIT 0, 10 OPTION max_matches = 5000;SHOW META]' in ..
why may it be?
You are trying to use the value as an field. The # fulltext operator (and indeed the whole of MATCH() full text query, operates on fields ONLY.
You've instead defined face as an atribute. Attributes don't work in full-text queries.
Can
Make face a field instead (remove the sql_attr_bigint) or make it both an attribute and field. (to do that, would have to duplicate it like you've duplicated the id, one for field, one for attribute. or use sql_field_string, but that makes a string attribute)
or
Use filter by the attribute instead. Dont really know how to do that in Foolz. But the SphinxQL query would be something like
SELECT * FROM nums WHERE `face` = 123456 LIMIT 0, 10

AS400 index configuration table

How can I view index of particular table in AS400? In which table index description of table is stored?
If your "index" is really a logical file, you can see a list of these using:
select * from qsys2.systables
where table_schema = 'YOURLIBNAME' and table_type = 'L'
To complete the previous answers: if your AS400/IBMi's files are "IBM's old style" Physical and Logical files, the qsys2.syskeys and qsys2.sysindexes are empty.
==> you retrieve index infos in QADBKFLD (for "indexes" info) and QADBXREF(for fields list) tables
select * from QSYS.QADBXREF where DBXFIL = 'YOUR_LOGICAL_FILE_NAME' and DBXLIB = 'YOUR_LIBRARY'
select * from QSYS.QADBKFLD where DBKFIL = 'YOUR_LOGICAL_FILE_NAME' and DBKLB2 = 'YOUR_LIBRARY'
WARNING: YOUR_LOGICAL_FILE_NAME is not your "table name", but the name of the file ! You have to join another table QSYS.QADBFDEP to match LOGICAL_FILE_NAME / TABLE_NAME :
To found indexes from your table's name:
Select r.*
from QSYS.QADBXREF r, QSYS.QADBFDEP d
where d.DBFFDP = r.DBXFIL and d.DBFLIB=r.DBXLIB
and d.DBFFIL = 'YOUR_TABLE_NAME' and d.DBFLIB = 'YOUR_LIBRARY'
To found all indexes' fields from your table:
Select DBXFIL , f.DBKFLD, DBKPOS , t.DBXUNQ
from QSYS.QADBXREF t
INNER JOIN QSYS.QADBKFLD f on DBXFIL = DBKFIL and DBXLIB = DBKLIB
INNER JOIN QSYS.QADBFDEP d on d.DBFFDP = t.DBXFIL and d.DBFLIB=t.DBXLIB
where d.DBFFIL = 'YOUR_TABLE_NAME' and d.DBFLIB = 'YOUR_LIBRARY'
order by DBXFIL, DBKPOS
if your indexes is create with SQL you can see liste of index in sysindexes system view
SELECT * FROM qsys2.sysindexes WHERE TABLE_SCHEMA='YOURLIBNAME' and
TABLE_NAME = 'YOURTABLENAME'
if you want detail columns for index you can join syskeys tables
SELECT KEYS.INDEX_NAME, KEYS.COLUMN_NAME
FROM qsys2.syskeys KEYS
JOIN qsys2.sysindexes IX ON KEYS.ixname = IX.name
WHERE TABLE_SCHEMA='YOURLIBNAME' and TABLE_NAME = 'YOURTABLENAME'
order by INDEX_NAME
You could also use commands to get the information. Command DSPDBR FILE(LIBNAME/FILENAME) will show a list of the objects dependent on a physical file. The objects that show a data dependency can then be further explored by running DSPFD FILE(LIBNAME/FILENAME). This will show the access paths of the logical file.

convert output of postgres query to utf8

I used postgresql
in my attachment table the filename_attachmnt column contains character with wrong format .
for example it contains : تكلي٠الزميل. احمدالوردي.pdf
the correct name it should be this : تكليف الزميل. احمدالوردي.pdf
I try without success using this query :
select encode(convert(cast(filename_attachmnt as bytea),'UTF8'),'escape') from attachment
updated :
this is the config of my database :
CREATE DATABASE "mobiltyDatabase"
WITH OWNER = postgres
ENCODING = 'SQL_ASCII'
TABLESPACE = pg_default
LC_COLLATE = 'C'
LC_CTYPE = 'C'
CONNECTION LIMIT = -1;
GRANT CONNECT, TEMPORARY ON DATABASE "mobiltyDatabase" TO public;
GRANT ALL ON DATABASE "mobiltyDatabase" TO postgres;