Why this simple kusto script is not working? - azure-data-explorer

The below print statement always returns empty string. Why is it happening?
let tspanString=strcat(tostring(toint(rand(100))),'d');
print totimespan(tspanString)

the result of strcat(N, 'd') is a non constant string in a format that can't be parsed into a timespan literal, when passed into totimespan().
A valid alternative in your case would be using rand(100) * 1d
See: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/datetime-timespan-arithmetic

Related

from django.db.models.Value not including quotes when converting to query string

I am using the django.db.models.Value expression within a QuerySet function in Django 3.2.8. When passing a string value ("|" in my example below), the conversion to a query string fails to add the ', which makes the query to fail.
from django.db import models
from django.db.models import F, Value
from django.db.models.functions import Concat
class PurchaseOrder(models.Model):
id = models.AutoField(primary_key=True)
customer_name = models.CharField(max_length=50)
date = models.DateField()
qs = PurchaseOrder.objects.annotate(
concat=Concat(
F("customer_name"),
Value("~"),
F("date"),
output_field=models.CharField(),
)
).values("concat")
>>> print(str(qs.query))
SELECT CONCAT("purchaseorder"."customer_name", CONCAT(~, "purchaseorder"."date")) AS "concat" FROM "purchaseorder"
As it can be seen from the result above, the ~ character is missing the two ' it should be wrapped around: CONCAT('~', "purchaseorder"."date").
Is this the expected functionality of expression Value or a bug that should be reported?
I am inclined to think it is a bug, because of the following:
I initially solved the problem above by writing it as Value("'~'"), with the two ' inside my string. However, when running the query in a sqlite3 database during unit testing I got an error in the query. I realised that sqlite has a different syntax than Postgres (my production and local dev database) for function Contact:
Postgres: CONCAT([args])
Sqlite: arg1 || arg2 ...
In the sqlite case, Django also wraps every argument in the concatenation with Coalesce:
COALESCE(arg1, '') || COALESCE(arg2, '')
The query that was resulting from this in sqlite looked like the one below:
... COALESCE("purchaseorder"."customer_name", ) || COALESCE('~', ) || COALESCE("purchaseorder"."date",)
(Note that I passed ' inside Value("'~'") this time)
The above query will give an error as the second argument inside COALESCE must not be empty ('' is an acceptable input).
If the above problem is due to a bug, what would be the best workaround to make the sqlite query work?
It seems to be a bug:
Inside django.db.models.functions.text.ConcatPair, method as_sqlite calls method coalesce:
class ConcatPair(Func):
...
def as_sqlite(self, compiler, connection, **extra_context):
coalesced = self.coalesce()
return super(ConcatPair, coalesced).as_sql(
compiler, connection, template='%(expressions)s', arg_joiner=' || ',
**extra_context
)
...
def coalesce(self):
# null on either side results in null for expression, wrap with coalesce
c = self.copy()
c.set_source_expressions([
Coalesce(expression, Value('')) for expression in c.get_source_expressions()
])
return c
This is the mechanism that wraps the arguments inside the concatenation with the COALESCE function, and as it can be seen, it is using Value(''). This means that expression Value is meant to be used directly with a string, as the expression above is expected to produce COALESCE([expression], '') in SQL.
I have not yet figured out what the exact problem is within Value, but below is a workaround for the COALESCE problem inside the concatenation. Simply override the coalesce method inside ConcatPair, adding ' inside Value:
from django.db.models.functions import ConcatPair, Coalesce
def _coalesce(self):
c = self.copy()
c.set_source_expressions(
[Coalesce(expression, Value("''")) for expression in c.get_source_expressions()]
)
return c
ConcatPair.coalesce = _coalesce

Create correct Criteria Operator

Trying to create a Criteria.Parse operator when I have to convert the string field to an Int.
Operation fails at the follwing:
Message=Parser error at line 0, character 15: syntax error;
("Convert.ToInt16{FAILED HERE}(awayML)>130")
Here is my code:
XPCollection collection = new XPCollection(session1, typeof(TodaysGame), CriteriaOperator.Parse("Convert.ToInt16(awayML)>130"));
int ct = collection.Count;
How do I form the Criteria using the Convert.ToInt16 function?
Criteria operators have their own syntax to convert string literals to int values. You need to use them instead of system Convert.ToInt function:
Function
Description
Example
ToInt(Value)
Converts Value to an equivalent 32-bit signed integer.
ToInt([Value])
ToLong(Value)
Converts Value to an equivalent 64-bit signed integer.
ToLong([Value])
You can check the full reference of DevExpress criteria syntax here
The correct way to build a Criteria like that would be:
CriteriaOperator.Parse("ToInt([awayML]) > 130");

Accessing elements of a map when using a variable key in Groovy

I'm trying to replace some characters in a String From a map
Case 1
​map= ['O':'0', 'L':'1', 'Z':'2', 'E':'3']
"Hey".toUpperCase().toCharArray().each{
print map.get(it,it)
}
The result is
HEY
Case 2 : I dont use toCharArray()
"Hey".toUpperCase().each{
print map.get(it,it)
}
The result is like expected
H3Y
So I tried several alternatives when using toCharArray(), and the only way to access the value is to use map."$it"
Why i can only use map."$it" to access my map when using toCharArray() ?
Because you are trying to get a value from a map using a char whilst every key there are String, and they are not equals:
assert !'E'.equals('E' as char)
$it works because it is converted to String:
e = 'E' as char
assert "$e".toString().equals('E')
(Note the toString() is needed, otherwise the comparison will happen between String and GStringImpl which are not equals)

how to convert an array of characters to qstring?

I have an array -
char name[256];
sprintf(name, "hello://cert=prv:netid=%d:tsid=%d:pid=%d\0", 1010,1200, 1300);
QString private_data_string = name;
At the last offset of this string i.e. '\0',when I try to do the following.
while(private_data_string.at(offset) != ':' &&
private_data_string.at(offset) != ';' &&
private_data_string.at(offset).isNull() == false)
The application aborts. Looks like that the data pointer is also zero at the string '\'. How can I fix this?
QString doesn't contain terminating character as you expect that is why you are failing assertion out of bounds. This is proper approach:
while(offset<private_data_string.length() &&
private_data_string.at(offset) != ':' &&
private_data_string.at(offset) != ';') {
// ...
}
It looks like you are doing something strange. Looks like your question is wrong. You are asking how to fix your strange solution of some mysterious problem, instead explain what are you trying to do and then as a bonus: how did you try to solve it.
You need to know several facts:
Writing \0 at tge end of your string literal is not necessary. String literals are null-terminated by default. Literal "abc" will actually contain 4 characters including terminating null character. Your string literal has 2 null characters at its end.
You have used the default constructor QString(char*). There is no additional data about buffer's length, so QString reads characters from the buffer until it encounters first null character. It doesn't matter how many null characters are actually at the end. The null character is interpreted as a buffer end marker, not a part of the string.
When you have QString "abc", its size is 3 (it would be surprising to have another value). Null character is not a part of the string. QString::at function can be used for positions 0 <= position < size(). This is explicitly specified in the documentation. So it doesn't matter if QString's internal buffer is null-terminated or not. Either way, you don't have access to null terminator.
If you really want null character to be part of your data, you should use QByteArray instead of QString. It allows to specify buffer size on construction and can contain as many null characters as you want. However, when dealing with strings, it's usually not necessary.
You should use QString::arg instead of sprintf:
QString private_data_string =
QString("hello://cert=prv:netid=%1:tsid=%2:pid=%3")
.arg(netid).arg(tsid).arg(pid);
sprintf is unsafe and can overrun your fixed-size buffer if you're not careful. In C++ there's no good reason to use sprintf.
"A QString that has not been assigned to anything is null, i.e., both the length and data pointer is 0" - this has nothing to do with your situation because you have assigned a value to your string.

Conversion from string "0.##" to type 'Integer' is not valid

i am doing a simple conversion from decimal to string and stripping trailing zeros like so:
argCat.ToString("0.##")
however, i keep getting the following error:
Conversion from string "0.##" to type 'Integer' is not valid.
am i missing something?
This would happen if argCat is of a type that does not have a ToString() overload that accepts a parameter.
In such a case, your code is parsed as ToString()("0.##"); the "0.##" becomes an argument to the indexer in the String returned by ToString().
You then get this misleading error because that indexer takes an int, not a string.
string str = String.Format("{0:C}", argCat);

Resources