Kusto: Failed to cast argument to scalar constant when using countof() - azure-data-explorer

I defined a UDF function in kusto:
.create-or-alter function with (docstring = 'abc', folder='udfs')
get_index_of(input:string, lookup:string)
{
countof(input, lookup)
}
Next, I am going to use it an a sample table and it does not work
datatable (Input:string, Lookup:string)
[
"text:1", ":"
]
| extend Result = get_index_of(Input, Lookup)
I get the error message:
countof(): failed to cast argument 2 to scalar constant
Do you have any idea what is wrong? Please note, that the function works, because a sample run return result:
print get_index_of('text', 'e')
1

as of this writing, the 2nd argument to countof() is expected to be a constant string literal (i.e., one that doesn't change based on row context)

Related

Kusto: Handling null parameter in user defined funtion

I am writing a custom User defined function in kusto where I want to have some optional parameters to the function which will be used in the "where" clause. I want to dynamically handle this. For example: If the value is present, then my where clause should consider that column filter, else it should not be included in the "where" clause>
Eg (psuedo code where value is not null):
function Calculate(string:test)
{
T | where test == test | order by timestamp
}
Eg (psuedo code where value is null or empty. My final query should look like this):
function Calculate(string:test)
{
T | order by timestamp
}
What is the efficient way to implement this. I will call this function from my c# class.
you can define a function with a default value for its argument, and use the logical or operator and the isempty() function to implement the condition you've described.
for example:
(note: the following is demonstrated using a let statement, but can be applied similarly to stored functions)
let T = range x from 1 to 5 step 1 | project x = tostring(x)
;
let F = (_x: string = "") {
T
| where isempty(_x) or _x == x
| order by x desc
}
;
F("abc")
if you run F() or F("") (i.e. no argument, or an empty string as the argument) - it will return all values 1-5.
if you run F("3") - it will return a single record with the value 3.
if you run F("abc") - it will return no records.

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

invalid object type while creating the function

I'm pretty new to PL/SQL and can't understand what's wrong.
I create new type
create or replace TYPE "hmdtype" is object(entity_id number, tipe varchar2(200), oper_id number, message varchar2(200))
Compile it, it's OK.
Then I'm trying to create function which returns this type:
create or replace FUNCTION HDM RETURN HMDTYPE AS
BEGIN
RETURN NULL;
END HDM;
Try to compile. The error is Error(1,21): PLS-00905: object U216_DM2_6350.HMDTYPE is invalid
Thanks in advance
if you define an object name surrounded by "" it is case sensitive.
by default (without "") the name will be converted to uppercase.
try create or replace FUNCTION HDM RETURN "hmdtype" AS
or redefine your type without ""
create or replace TYPE hmdtype is object(entity_id number, tipe varchar2(200), oper_id number, message varchar2(200))
and your code should work
Hello you can use the exact name as you have compiled as "" means exact name whatever you have given during compilation. Below code you can check it works
CREATE OR REPLACE TYPE "test_object" IS OBJECT
(
F_NM VARCHAR2(100),
L_NM VARCHAR2(100)
);
CREATE OR REPLACE FUNCTION test_function RETURN
"test_object"
AS
BEGIN
NULL;
END;

If exists in R using this

I want to see if a variable exists - i.e. that I have created in.
if(exists(this.mydict))
{ //append my dict
}else
{
// initialize dict
}
Trouble is this fails on
Error in exists(this.mydict)
What am I doing wrong?
How can I extend the exists function to work with the following:
Any ideas how I would extend to this to looking at seeing whether a nested dictionary would also exist. I.e. for example: if(exists("mylists[[index]]['TSI']")), where the mylists object is a dictionary look up that also wants to contain a nested dictionary.
exists() function takes a character argument with the variable name:
if(exists("this.mydict")){
# you can use this.mydict here
}else{
# initialize this.mydict
# e.g. this.mydict <- "some value here"
}

How to cast a value type to Map in Rascal?

I have a variable of type value that stores a map, but I can not access the values by providing the keys:
rascal>a
value: ("s":"s")
rascal>a["s"]
|stdin:///|(2,3,<1,2>,<1,5>): subscript not supported on value at |stdin:///|(2,3,<1,2>,<1,5>)
☞ Advice
How can I parse the value to map in order to be able to retrieve my value ?
if (map[str,str] myMap := a) {
// do stuff with myMap
}
else {
throw "<a> is not a map?";
}
Another way of "narrowing types" is using pattern matching in function parameters:
rascal>value x = 1;
int: 1
rascal>int myFunc(int i) = 2 * i;
ok
rascal>myFunc(x);
int: 2
And yet another way is using visit or switch:
visit(bigValue) {
case Expression e => ...work with e...
}
The general idea is:
pattern matching means narrowing (downcasting)
pattern matching may fail and so is always in a conditional context
there are many places in Rascal where you can use pattern matching: function dispatch, switch, visit, :=, <-

Resources