Accented and unaccented letters are equal in MariaDB - mariadb

I have a table in a MariaDB database, which contains words of any language. The problem is that, for example, 'a' == 'á' is considered true.
MariaDB [(none)]> select 'a' = 'á';
+------------+
| 'a' = 'á' |
+------------+
| 1 |
+------------+
The words' column is marked UNIQUE in the table, which is good to prevent duplicates, but it treats, for example, 'arat' and 'árát' the same, so the insertion of 'arat' fails if 'árát' is already present, which is not the expected behaviour, both words should be allowed to present in the table parallelly.
I'm using MariaDB 10.7.3-1 on ArchLinux.
How to set MariaDB to differentiate these words?

Use COLLATE like below to do the comparison in character set.
SELECT 'str1' = 'str2' COLLATE <charset>;

Related

How to keep sequence when using TEXT type as primary key of a SQLite table?

I have a sqlite table below:
panel_name
layer
asset_name
ls_ui_main
2
pfb_ls_ui_main
ss_ui_main
2
pfb_ss_ui_main
And the pk is "panel_name".
When I added a new row "| ms_ui_main | 2 | pfb_ms_ui_main |" to the table and wrote the change, the sequence was changed.
I used command "SELECT panel_name FROM ui_panel_info" and got result that:
panel_name
ls_ui_main
ms_ui_main
ss_ui_main
And then "SELECT asset_name FROM ui_panel_info" got result that:
asset_name
pfb_ls_ui_main
pfb_ss_ui_main
pfb_ms_ui_main
It's doesn't matter the ms is above the ss. But I need the other columns are the same sequence.
And I found when I did some changes I didn't what, such as modify table definition etc, later the "SELECT asset_name FROM ui_panel_info" got the correct sequence.
What happend? How to fix it?

Is it possible to distinguish similarly named properties belonging to same vertex in a MATCH query in Nebula Graph?

I'm playing with Nebula Graph 2.0.0.
I create two tags, both contain a property called name:
create tag t1(name string)
create tag t2(name string)
Now I insert a vertex giving it t1.name property:
> insert vertex t1(name) values '1': ('first-name');
Execution succeeded (time spent 2730/95913 us)
I can see that it can be found by ID:
> match (x:t1) where id(x) == '1' return x
+-------------------------------+
| x |
+-------------------------------+
| ("1" :t1{name: "first-name"}) |
+-------------------------------+
Got 1 rows (time spent 2713/95756 us)
I can also find it by ID and t1.name:
> match (x:t1) where id(x) == '1' and x.name == 'first-name' return x
+-------------------------------+
| x |
+-------------------------------+
| ("1" :t1{name: "first-name"}) |
+-------------------------------+
Got 1 rows (time spent 2827/100963 us)
Now I assign t2.name to the same vertex:
insert vertex t2(name) values '1': ('second-name');
It is added ok:
> match (x:t1) where id(x) == '1' return x
+--------------------------------------------------------+
| x |
+--------------------------------------------------------+
| ("1" :t1{name: "first-name"} :t2{name: "second-name"}) |
+--------------------------------------------------------+
Got 1 rows (time spent 3579/96685 us)
And I can still search by ID and t1.name:
> match (x:t1) where id(x) == '1' and x.name == 'first-name' return x
+--------------------------------------------------------+
| x |
+--------------------------------------------------------+
| ("1" :t1{name: "first-name"} :t2{name: "second-name"}) |
+--------------------------------------------------------+
Got 1 rows (time spent 2534/96306 us)
But when I search by ID and t2.name, nothing gets found:
> match (x:t1) where id(x) == '1' and x.name == 'second-name' return x
Empty set (time spent 3383/96788 us)
So, probably, under the hood, the system thinks I want to search by t1.name, so it finds nothing.
In a different session, with tags named differently, I got a different behavior: after adding a second name property, I lost ability to search by first name, but it was possible to search using the second name.
Here are my questions:
Is it even legal to have on same vertex properties with same name (but coming from different tags)?
If so, how can I ask the query executor to use the specific property (for instance, t1.name or t2.name and not the one that the system chooses automatically)?
Good catch! Tag is not that native to OpenCypher actually, we nebula is working work support more and more OpenCypher features, and to make it better.
1 Under the hood, the vertex property matching is based on the nebula index, which is now based on one tag only for now(it's actually left RocksDB key match).
2 when the condition/index matching was done, in MATCH call, you can return all tags' props belongs to it.
Is it even legal to have on same vertex properties with same name (but coming from different tags)?
It's legal. But maybe in most cases, the name could be the same in both tags?
Actually, here the WHERE CLAUSE: where id(x) == '1' is like a Primary Key, thus one Vertex is specified already. In your use case, is it still needed for further AND condition, please?
If so, how can I ask the query executor to use the specific property (for instance, t1.name or t2.name and not the one that the system chooses automatically)?
For the reason: 1(prop index can support only one tag/edge type) now, we can only filter within one tag, thus it's either t1.name or t2.name, like t1.name == "foo" and t1.age > 18.
The interesting case you found(👍🏻) is because the prop-index-selection(which is rule based selection, for now, there will be more improvements on this) cannot be done due to id(v) == 123 is not prop-index based and both tags' prop-indexes are of "name".
To avoid this, maybe we shouldn't allow the same prop-name across tags that belong to the same vertex with different values, this could be improved from docs or code.

MariaDB regexp_replace backreference not working as expected

I have this simple regex in a user defined function
set mm = regexp_replace(in_str, '^M([0-9]+(\.[0-9]+)?).*$', '\\1');
when passing in 'M56-5' in MariaDB 10.1 I would get "56" as expected but in MariaDB 10.4 I get an error "Data truncated for column 'mm' at row 1". When I pass in 'M56.5' I get "56.5" in both versions as expected. Did something change?
I figured it out. I mistakenly was using a single backslash to escape the "." whereas it is required to use 2 backslashes when escaping special characters, one for the MariaDB parser and one for the regex library. https://mariadb.com/kb/en/regular-expressions-overview/#escaping
mysql> SELECT regexp_replace('M56-5 foo', '^M([0-9]+(\.[0-9]+)?).*$', '$1');
+---------------------------------------------------------------+
| regexp_replace('M56-5 foo', '^M([0-9]+(\.[0-9]+)?).*$', '$1') |
+---------------------------------------------------------------+
| 56-5 |
+---------------------------------------------------------------+
(That is using MySQL 8.0.31 -- There has been some inconsistencies lately in the syntax of regexps for MySQL and MariaDB versions.)

Why does end-of-line operator ($) not work in MariaDB unless I include a trailing null?

This is the field of interest:
something VARCHAR(8) NULL,
It can contain non-digits, but I need to select for rows that contain only digits in this field. I have tried to use this regular expression:
something RLIKE '^\\d+$'
This fails to match. However, if I add a Kleene closure for null bytes at the end, it matches. This is the expression that matches:
something RLIKE '^\\d+\x00*$'
My question is: am I doing something wrong? Is there a flag I should have set? I don't see this mentioned in the documentation anywhere. MariaDB's documentation does not mention padding VARCHARs with null bytes. In fact, a section in their documentation leaves me with the impression that my first regular expression should have worked. Here is a quote from the documentation:
This example checks if the string consists of "word" characters only:
SELECT 'abc' RLIKE '^\\w+$';
-> 1
You don't give version or code samples, but the following works in MariaDB 10.3.9 with default settings:
CREATE TABLE r (x VARCHAR(8) NULL);
INSERT INTO r VALUES ('abc'),('123'),('1d3');
SELECT x RLIKE '^\\d+$' FROM r;
+------------------+
| x RLIKE '^\\d+$' |
+------------------+
| 0 |
| 1 |
| 0 |
+------------------+
https://mariadb.com/kb/en/library/server-system-variables/#default_regex_flags has some behavior flags, but I don't know if this is relevant to your case.

Joining odd/even results of select for subtraction in sqlite?

I've got an sqlite table which contains start/stop timestamps. I would like to create a query which returns a total elapsed time from there.
Right now I have a SELECT (e.g. SELECT t,type FROM event WHERE t>0 AND (name='start' or name='stop) and eventId=xxx ORDER BY t) which returns a table which looks something like this:
+---+-----+
|t |type |
+---+-----+
| 1|start|
| 20|stop |
|100|start|
|150|stop |
+---+-----+
To produce the total elapsed time in the above example would be accomplished by (20-1)+(150-100) = 69
One idea I had was this: I could run two separate queries, one for the "start" fields and one for the "stop" fields, on the assumption that they would always line up like this:
+---+---+
|(1)|(2)|
+---+---+
| 1| 20|
|100|150|
+---+---+
(1) SELECT t FROM EVENT where name='start' ORDER BY t
(2) SELECT t FROM EVENT where name='stop' ORDER BY t
Then it would be simple (I think!) to just sum the differences. The only problem is, I don't know if I can join two separate queries like this: I'm familiar with joins that combine every row with every other row and then eliminate those that don't match some criteria. In this case, the criteria is that the row index is the same, but this isn't a database field, it's the order of the resulting rows in the output of two separate selects - there isn't any database field I can use to determine this.
Or perhaps there is some other way to do this?
I do not use SQLite but this may work. Let me know.
SELECT SUM(CASE WHEN type = 'stop' THEN t ELSE -t END) FROM event
This assumes the only values in type are start/stop.

Resources