hasura_session invocation without arguments - hasura

There is a function:
CREATE OR REPLACE FUNCTION public.drops(cases_free_row cases_free, hasura_session json)
RETURNS SETOF drops
LANGUAGE sql
STABLE
AS $function$
SELECT *
FROM drops d
WHERE d.caseid = cases_free_row.id
AND d.userid = (hasura_session ->> 'x-hasura-user-id') :: INT
$function$
When I try to call, I need to enter the arguments
{
"errors": [
{
"extensions": {
"path": "$.selectionSet.cases_free.drops.args",
"code": "not-supported"
},
"message": "Non default arguments cannot be omitted"
}
]
}
Is it possible to get data without entering arguments?
Hasura v1.2.0-beta.3

You need the first args cases_free_row but for the second args hasura_session there, here's how to make it available to your function:
In Hasura Console go to Data, under Untracked Custom Functions, click track.
Your custom function will appear on left side panel, click to open
Then under Session argument insert hasura_session

Your specific postgres function requires arguments, so no.

Related

Kusto extractjson not working with email address

I am attempting to use the extractjson() method that includes email addresses in the source data (specifically the # symbol).
let T = datatable(MyString:string)
[
'{"user#domain.com": {"value":10}, "userdomain.com": { "value": 5}}'
];
T
| project extractjson('$.["user#domain.com"].value', MyString)
This results in a null being returned, changing the JSONPath to '$.["userdomain.com"].value' does return the correct result.
Results
I know the # sign is a used as the current node in a filter expression, does this need to be escaped when used with KQL?
Just as a side note, I run the same test using nodes 'jsonpath' package and this worked as expected.
const jp = require('jsonpath');
const data = {"user#domain.com": {"value":10}, "name2": { "value": 5}};
console.log(jp.query(data, '$["user#domain.com"].score'));
you can use the parse_json() function instead, and when you don't have to use extract_json():
print MyString = '{"user#domain.com": {"value":10}, "userdomain.com": { "value": 5}}'
| project parse_json(MyString)["user#domain.com"].value
MyString_user#domain.com_value
10
From the documentation: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/extractjsonfunction

Does Boto3 DynamoDB have reserved attribute names for update_item with conditions expressions? Unexpected attribute SET behavior

I've implemented a simple object versioning scheme that allows the calling code to supply a current_version integer that that will set the ConditionExpression. I've also implemented a simple timestamping scheme to set an attribute named auto_timestamp to the current unix timestamp.
When the ConditionExpression is supplied with the object's current version integer, the update occurs, but also sets auto_timestamp to the current version value, rather than the value supplied in ExpressionAttributeValues. This only occurs if the attribute names are #a0, #a1 ... and values are :v0, :v1 ...
For example, this runs as expected without the condition, and auto_timestamp is set to 1643476414 in the table. The if_not_exists is used to start the object version at 0 if the item does not yet exist or did not previously have a auto_object_version attribute.
update_kwargs = {
"Key": {"user_id": user_id},
"UpdateExpression": 'SET #a0 = :v0, #a1 = if_not_exists(#a1, :zero) + :v1',
"ExpressionAttributeNames": {"#a0": "auto_timestamp", "#a1": "auto_object_version"},
"ExpressionAttributeValues": {":v0": 1643476414, ":v1": 1, ":zero": 0}
}
table.update_item(**update_kwargs)
However, this example runs without exception, but auto_timestamp is set to 1. This behavior continues for each subsequent increment of current_version for additional calls to update_item
from boto3.dynamodb.conditions import Attr
update_kwargs = {
"Key": {"user_id": user_id},
"UpdateExpression": 'SET #a0 = :v0, #a1 = if_not_exists(#a1, :zero) + :v1',
"ExpressionAttributeNames": {"#a0": "auto_timestamp", "#a1": "auto_object_version"},
"ExpressionAttributeValues": {":v0": 1643476414, ":v1": 1, ":zero": 0}
"ConditionExpression": Attr("auto_object_version").eq(1)
}
table.update_item(**update_kwargs)
While debugging, I changed the scheme by which I am labeling the attribute names and values to use #att instead of #a and :val instead of :v and the following works as desired and auto_timestamp is set to 1643476414:
from boto3.dynamodb.conditions import Attr
update_kwargs = {
"Key": {"user_id": user_id},
"UpdateExpression": 'SET #att0 = :val0, #att1 = if_not_exists(#att1, :zero) + :val1',
"ExpressionAttributeNames": {"#att0": "auto_timestamp", "#att1": "auto_object_version"},
"ExpressionAttributeValues": {":val0": 1643476414, ":val1": 1, ":zero": 0}
"ConditionExpression": Attr("auto_object_version").eq(1)
}
table.update_item(**update_kwargs)
I couldn't find any documentation on reserved attribute names or values that shouldn't be used for keys in ExpressionAttributeNames or ExpressionAttributeValues.
Is this behavior anyone has witnessed before? The behavior is easily worked around when switching the string formatting used to generate the keys but was very unexpected.
There are no reserved attribute or value names, and I routinely use names like :v1 and #a1 in my own tests, and they seem to work fine.
Assuming you correctly copied-pasted your code into the question, it seems to me you simply have a syntax error in your code - you are missing a double-quote after the "auto_timestamp. What I don't understand, though, is how this compiles or why changing a to att changed anything. Please be more careful in pasting a self-contained code snippet that works or doesn't work.

Extracting values with jq only when they exist

I have a large file of records that contain fields that look something like this:
{
"id": "1000001",
"updatedDate": "2018-12-21T01:52:00Z",
"createdDate": "1993-11-30T02:59:25Z",
"varFields": [
{
"fieldTag": "b",
"content": "1000679727"
},
{
"fieldTag": "v",
"content": "v.1"
}
}
I need to extract the .content element along with other things, but only when the fieldTag associated with it is "v". Only some records contain a fieldTag "v".
When I try to parse using
(.varFields[] |select(.fieldTag=="v") | "\(.content)") // ""
it works fine so long as v is present. However, when it is not present, I get
jq: error (at <stdin>:353953): Cannot iterate over null (null)
I tried to get rid of the error with multiple variations, including things to the effect of
(select((.varFields[] |select(.fieldTag=="v") | .content) != null) | .varFields[] |select(.fieldTag=="v") | "\(.content)") // ""
but I'm still getting the same error. What am I missing?
Take a look at the error suppression operator ? that works a bit like the new ?. nullable chaining operator in Javascript.
The ? operator, used as EXP?, is shorthand for try EXP.
Example:
jq '[.[]|(.a)?]'
Input [{}, true, {"a":1}]
Output [null, 1]
They have a slightly simpler demonstrable example of this at https://jqplay.org/jq?q=%5B.%5B%5D%7C(.a)%3F%5D&j=%5B%7B%7D%2C%20true%2C%20%7B%22a%22%3A1%7D%5D and the try-catch operator is similar if all you need is custom error handling (or just error ignoring...).

CosmosDB SQL query syntax for if statement

I'm trying to find the correct syntax for doing an If/Case type of statement in an Azure ComsmosDB SQL query. Here is the document that I have
{
"CurrentStage": "Stage2",
"Stage1": {
"Title": "Stage 1"
},
"Stage2": {
"Title": "Stage 2"
},
"Stage3": {
"Title": "Stage 3"
}
}
What I want to do is create a query that looks something like
Select c.CurrentStage,
if (CurrentStage == 'Stage1') { c.Stage1.Title }
else if (CurrentStage == 'Stage2') { c.Stage2.Title }
else if (CurrentStage == 'Stage3') { c.Stage3.Title } as Title
From c
Obviously the document and query that I have is a lot more complicated then this, but this gives you the general idea of what I'm trying to do. I have 1 of the fields in the select to be variable based on some other fields in the document.
While udf suggested by Jay Gong may be more comfortable to use if you need to reuse this function a lot, you can do this without udf using ternary operator syntax.
For example:
select
c.CurrentStage = 'stage1' ? c.Stage1.Title
: c.CurrentStage = 'stage2' ? c.Stage2.Title
: c.CurrentStage = 'stage3' ? c.Stage3.Title
: 'your default value should you wish one'
as title
from c
Advice: Provider SQL solution has the benefit over UDF that it is self-contained and does not require setting up the logic on the server before executing. Also, note that logic versioning is simpler if logic is stored in client apps entirely, not shared across client and server as in the UDF case. UDF does have it's uses (ex:heavy reuse across queries), but usually it's better to do without.
I suggest you using User Defined Function in Cosmos DB.
udf code:
function stage(c){
switch(c.CurrentStage){
case "Stage1" : return c.Stage1.Title;
case "Stage2" : return c.Stage2.Title;
case "Stage3" : return c.Stage3.Title;
default: return "";
}
}
SQL :
Select c.CurrentStage,
udf.stage(c) as Title
From c
Output result:
Hope it helps you.

are there any events related to awful.prompt in Awesome WM 3.5?

I would like to know if it is possible to catch events from an awful.prompt widget like an event when the widget is activated with:
myprompt:run()
or when the user press Enter to validate his entry or Esc to leave/quit this widget.
There isn't a way to directly connect a signal on an awful.widget.prompt, but it is possible to specify some instructions to the prompt widget when the command has been executed:
in the awful/widget/prompt.lua the run function launch awful.prompt.run():
local function run(promptbox)
return prompt.run({ prompt = promptbox.prompt },
promptbox.widget,
function (...)
local result = util.spawn(...)
if type(result) == "string" then
promptbox.widget:set_text(result)
end
end,
completion.shell,
util.getdir("cache") .. "/history")
end
with some parameters which are :
args A table with optional arguments: fg_cursor, bg_cursor, ul_cursor, prompt, text, selectall, font, autoexec.
textbox The textbox to use for the prompt.
exe_callback The callback function to call with command as argument when finished.
completion_callback The callback function to call to get completion.
history_path Optional parameter: file path where the history should be saved, set nil to disable history
history_max Optional parameter: set the maximum entries in history file, 50 by default
done_callback Optional parameter: the callback function to always call without arguments, regardless of whether the prompt was cancelled.
changed_callback Optional parameter: the callback function to call with command as argument when a command was changed.
keypressed_callback
So I just have to use awful.prompt.run on my prompt box and specify the done_callback
Example: a prompt box in a wibox. The wibox is shown when the Mod4 + r keys are pressed, the wibox is hidden when the command is executed:
awful.key({ modkey }, "r", function ()
--promptlist is a table that contains wibox for each screen
if promptlist[mouse.screen].visible == false then
promptlist[mouse.screen].visible=true
awful.prompt.run({
prompt = promptlist.prompt[mouse.screen].prompt },
promptlist.prompt[mouse.screen].widget,
function (...)
local result = awful.util.spawn(...)
if type(result) == "string" then
promptlist.prompt[mouse.screen].widget:set_text(result)
--promptlist.prompt table that contains prompt widget for each screen
end
end,
awful.completion.shell,
awful.util.getdir("cache") .. "/history",
50,
function()
promptlist[mouse.screen].visible = false
end
)
else
promptlist[mouse.screen].visible=false
end
end),

Resources