MariaDB and ipv6 operations - mariadb

Why does this query return correct result in the MySQL and null result in the MariaDB?
select inet6_ntoa(inet6_aton('200d:31c4:1905:9eb2:3c7f:c45c:de78:42cd') & ((~INET6_ATON('::') << (128 - 97))))
Returns in the MySQL:
200d:31c4:1905:9eb2:3c7f:c45c:8000::
Returns in the MariaDB:
null

It looks like the issue is in the ~ operator. For MariaDB it is defined as follow:
Bitwise NOT. Converts the value to 4 bytes binary and inverts all bits.
When applied to the result of INET6_ATON() the length of the binary value get truncated. The query
select HEX(INET6_ATON('::')), HEX(~INET6_ATON('::'))
in MariaDB will produce the following values:
HEX(INET6_ATON('::')) -> 00000000000000000000000000000000
HEX(~INET6_ATON('::')) -> FFFFFFFFFFFFFFFF
(interestingly, it converts the value to 8 bytes instead of 4 bytes, at least for the MariaDB server running on https://dbfiddle.uk/)
Where as in MySQL the bitwise negate operator will produce the following value:
HEX(INET6_ATON('::')) -> 00000000000000000000000000000000
HEX(~INET6_ATON('::')) -> FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
From there on, in MariaDB, all remaining bit operations you have like shifting and & will fail or will produce incorrect values, which ultimately results in 0 or null, where in MySQL you will get the correct result.

Related

CREATE FUNCTION throws SQL Error (1064) (42000)

I'm trying to create a stored function in a MariaDB database.
I copied the function I'm trying to create from the MariaDB Docs:
DELIMITER //
CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
DECLARE x TINYINT;
SET x = 42;
RETURN x;
END
//
DELIMITER ;
Unfortunately, I get the following error:
SQL Error [1064] [42000]: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3
What baffles me most is that the given code is supposed to resolve the very error code I'm getting according to the MariaDB docs
The solution is to specify a distinct delimiter for the duration of the process, using the DELIMITER command
It turned out, the client I used to issue the command, DBeaver, was causing the trouble.
After switching over to MySqlWorkbench everything worked as expected.
Apparently, DBeaver didn't recognise the delimiters correctly..
I think you may have forgotten to select the database you want this routine to be stored into.
So try adding a use as the first line
use `test`;
DELIMITER //
CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
DECLARE x TINYINT;
SET x = 42;
RETURN x;
END
//
DELIMITER ;

Run Keyword If has invalid syntax

Why is the following Robot statement complaining about 'Convert To Integer' keyword is invalid syntax? Thanks
Run Keyword If Convert To Integer ${packets_2} <= Convert To Integer ${packets_1}
... FAIL ${\n}[FAILED] Packets 2 not greater than packets 1.
... ${\n}packets_time1: ${packets_1} ${\n}packets_time2: ${packets_2}
You cannot call a keywords as the condition for Run Keyword If. The first argument is expected to be a python expression. Since you're trying to do a comparison of an integer, you can do that directly in the expression like so:
Run keyword if int('${packets_2}') <= int('${packets_1})
... FAIL \n[FAILED] Packets 2 not greater than packets 1
The other problem is that you are supplying two other arguments: ${\n}packets_time1: ${packets_1} and ${\n}packets_time2: ${packets_2}. It's not clear what you think those are for. I'm guessing you want them as part of the error message. If that's the case, it will have to be all on one line or else robot will think they are extra arguments to the FAIL keyword.
Run keyword if int('${packets_2}') <= int('${packets_1})
... FAIL \n[FAILED] Packets 2 not greater than packets 1\n$packets_time1: ${packets_1}\npackets_time2: ${packets_2}

Python3 | SQL request failed

So. Simple request SELECT * FROM access WHERE {arg}=TRUE, where arg = "friends_grinder".
File "/root/python/NaVK/source/main/FriendsGrinderEngine.py", line 51, in __routine
users = ADB.get_authorized_users('friends_grinder')
File "/root/python/NaVK/source/database/AccessDB.py", line 30, in get_authorized_users
users = self.__conn.cursor().execute(f'SELECT * FROM access WHERE {arg}=TRUE').fetchall()
sqlite3.OperationalError: no such column: TRUE
I don't get this error on windows. But I get it on Ubuntu.
friends_grinder column is BOOLEAN.
From the documentation:
Beginning with SQLite 3.23.0 (2018-04-02), SQLite recognizes the identifiers "TRUE" and "FALSE" as boolean literals, if and only if those identifiers are not already used for some other meaning. If there already exists columns or tables or other objects named TRUE or FALSE, then for the sake of backwards compatibility, the TRUE and FALSE identifiers refer to those other objects, not to the boolean values.
The boolean identifiers TRUE and FALSE are usually just aliases for the integer values 1 and 0, respectively. However, if TRUE or FALSE occur on the right-hand side of an IS operator, then they form new unary postfix operators "IS TRUE" and "IS FALSE" which test the boolean value of the operand on the left.
If you're getting no such column: TRUE as an error, that means the version of sqlite being used on that system is too old to recognize the identifier. Upgrade, or use 1 instead.

PostScript forall on dictionaries

According to the PLRM it doesn't matter in which order you execute a forall on a dict:
(p. 597) forall pushes a key and a value on the operand stack and executes proc for each key-value pair in the dictionary
...
(p. 597) The order in which forall enumerates the entries in the dictionary is arbitrary. New entries put in the dictionary during the execution of proc may or may not be included in the enumeration. Existing entries removed from the dictionary by proc will not be encountered later in the enumeration.
Now I was executing some code:
/d 5 dict def
d /abc 123 put
d { } forall
My output (operand stack) is:
--------top-
/abc
123
-----bottom-
The output of ghostscript and PLRM (operand stack) is:
--------top-
123
/abc
-----bottom-
Does it really not matter in what order you process the key-value pairs of the dict?
on the stack, do you first need to push the value and then the key, or do you need to push the key first? (as the PLRM only talks about "a key and a value", but doesnt tell you anything about the order).
Thanks in advance
It would probably help if you quoted the page number qhen you quote sections from the PLRM, its hard to see where you are getting this from.
When executing forall the order in which forall enumerates the dictionary pairs is arbitrary, you have no influence over it. However forall always pushes the key and then the value. Even if this is implied in the text you (didn't quite) quote, you can see from the example in the forall operator that this is hte case.
when you say 'my output' do you mean you are writing your own PostScript interpreter ? If so then your output is incorrect, when pushing a key/value pair the key is pushed first.

PostgreSQL CASE statement syntax error

I'm trying to follow the instructions in the PostgreSQL manual.
PostgreSQL: Documentation: 9.1: Control Structures
My PostgreSQL server is version 9.1.14 on Windows 32-bit.
The following SQL statement is unexpectedly resulting in a syntax error:
SELECT
CASE 1
WHEN 1,2 THEN 'x'
ELSE 'y'
END;
I'm expecting it to return 'x';
The more traditional code runs fine, however:
SELECT
CASE 1
WHEN 1 THEN 'x'
WHEN 2 THEN 'x'
ELSE 'y'
END;
You are using the CASE syntax as provided by the procedural language plpgsql. This is similar but not identical to the SQL CASE syntax. Here is the link to the SQL version of CASE.
Here you see, that 1,2 is not allowed, only a plain expression. So you could write:
SELECT
CASE
WHEN 1 in (1,2) THEN 'x'
ELSE 'y'
END;

Resources