typedb.common.exception.TypeDBClientException: [QRY16] Invalid Query Pattern - vaticle-typedb

When i am trying to fetch count. getting this below error
``[QRY16] Invalid Query Pattern: The pattern '{{ $xy isa taggedwith; $xy ($x, $y); $x has $_0; $x isa Person; $y isa Employer; $_0 = "ab333a1a-0688-4d70-a9da-32b095a69223"; $_0 isa unique_id; }}' can never be satisfied the current schema, specifically due to '[{ $xy isa taggedwith; $xy ($x, $y); $x has $_0; $x isa Person; $y isa Employer; $_0 = "ab333a1a-0688-4d70-a9da-32b095a69223"; $_0 isa unique_id; }]'.
Please check server logs for the stack trace`.`
Actual Query i am using:
match $x isa Person; {$x id ab333a1a-0688-4d70-a9da-32b095a69223;}; $xy ($x, $y) isa taggedwith; $y isa Employer; get $y; count;
I want to fetch count, without any issues.

This error indicates that you've written a query that is not semantically valid according to your schema. For example, it's possible that a Person or an Employer cannot be part of a taggedwith relation, which means this query will never find any results.
The best way to debug this error is to partition your query into smaller parts that are not invalid, then add the pieces back one by one until you find the part of the query that causes the error.
Also, it looks like the id keyword should not be valid. There is a TypeQL keyword (in version 2.8.0) called iid but it requires a hex input, such as $x iid 0x123.... If id is an attribute you have created on Person, you'll want to use $x has id "ab333a1a-0688-4d70-a9da-32b095a69223" as a string attribute.
Hope this helps!

Related

How to Redirect to different pages using branch in Oracle Apex?

I have defined a function returning a URL(redirect).
branch
Page 1: Home-
Pre-Rendering-
Before Header-
Branches
With the following script:
declare
x number:=1;
myurl varchar2(255);
begin
if v('AGENCY') = 'R-AG' then
x := 3;
myurl := 'f?p=&APP_ID.:3:&SESSION.'; ---page 3
else
x := 50;
myurl := 'f?p=&APP_ID.:50:&SESSION.'; --- page 50
end if;
return myurl;
end;
I have defined item applications
Name : AGENCY
Scope : Application
Session State Protection: Unrestricted
I have defined an application computation
Sequence :10
Computation Item: AGENCY
Computacion Point: After
Authentication Computacion Type: SQL Query(return single value)
Computacion:
SELECT ROL
FROM USERS;
But for some reason the branch only took page 3 as priority and "else" is not fulfilled to redirect to page 50 when it is the case.
Your computation looks like something that should have a filter - how many rows return from a select from 'users' with no filter?
Though if there were any issues from that, I would have thought p50 would be the result.
You could also do this more declaratively. As in, have a branch to page 3 when item AGENCY = R-AG, and a second branch to p50 with no condition.
You first branch to p3 could also have just a query returning rows, such as
select null
from users
where username = :app_user -- or whatever your filter should probably be here
and rol = 'R-AG'

How to include "citation" attributes/properties in graphs?

I am creating a domain-specific model which includes entities that have attributes whose original source or citation needs to be defined.
In graql for example:
define
"country" sub entity
has population;
"evidence" sub attribute datatype string;
"population" sub attribute datatype string
has evidence;
This seems to define an attribute of an attribute, and conceptually seems to make the meaning of the attribute dependent on a certain context, which is arguably better modelled as annotated "fact" entities with relationships to other entities.
What is the simplest way to model attributes like these without increasing complexity of the model?
Attributes of attributes
Attributes of attributes don't necessarily work as you might expect. It's important to remember that in Grakn there will be only one node in the graph for an attribute of a particular type with a particular value.
That is to say an attribute of type population value sixty million will only occur once in the knowledge graph.
If we change your schema slightly to add names for countries (also there's no need for single quotes around types):
define
country sub entity
has population,
has name;
name sub attribute datatype string;
evidence sub attribute datatype string;
population sub attribute datatype string
has evidence;
Then add two countries to the knowledge graph:
insert $uk isa country, has name 'UK', has population $p; $p 'sixty million' has evidence 'journal';
insert $fr isa country, has name 'France', has population $p; $p 'sixty million' has evidence 'wikipedia';
commit;
What we can see if we visualise it is that we can't tell the source of the population for each country separately, because both of the countries and both of the pieces of evidence are connected to the same population instance.
(Visualised in Grakn Workbase Visualiser)
Attributes of attributes make sense in a case like:
attribute phrase value Hi there! owning an attribute language value English. That is, the language attribute is referring to the value of the phrase attribute.
This means that if you want to record the source of an attribute you'll need to do things differently. I suggest three possible options. Note, that for each of the following three ideas population shouldn't own evidence for the reason mentioned. In the schema above population sub attribute datatype string has evidence; should become population sub attribute datatype string;
1. Implicit relationships
Under the hood Grakn has implicit relationships to implement attribute ownership, always autogenerated and prefixed with #has-, for example #has-population. We can attach attributes to these implicit relationships!
First delete the instances we inserted above (this will delete all entities and attributes in the graph, beware!):
match $x isa entity; $y isa attribute; delete $x, $y;
Then define that the implicit population attribute can own evidence and add examples:
define #has-population has evidence;
insert $uk isa country, has name 'UK', has population $p via $r; $p 'sixty million'; $r has evidence 'journal';
insert $fr isa country, has name 'France', has population $p via $r; $p 'sixty million'; $r has evidence 'wikipedia';
Now we're able to disambiguate the evidence for the UK's population from the evidence for France's population. We can query for this:
match $c isa country, has name $n, has population $p via $r;
$p 'sixty million'; $r has evidence $e; get $n, $e;
Result:
{$n val "France" isa name; $e val "wikipedia" isa evidence;}
{$n val "UK" isa name; $e val "journal" isa evidence;}
2. Relationships to implicit relationship
If the evidence is more complex than a single attribute, then it may be better modelled as a relationship, in which #has-population plays a role.
define
information-sourcing sub relationship,
relates sourced-information,
relates information-source;
#has-population plays sourced-information;
publication sub entity,
plays information-source;
insert $uk isa country, has name 'UK', has population $p via $r; $p 'sixty million'; $pub isa publication; $i(sourced-information: $r, information-source: $pub) isa information-sourcing;
insert $uk isa country, has name 'France', has population $p via $r; $p 'sixty million'; $pub isa publication; $i(sourced-information: $r, information-source: $pub) isa information-sourcing;
3. A normal relationship
Finally, you could create a relationship that links the population, country, and evidence, that avoids using implicit relationships if these seem too complex.
Conclusion
Which method to use depends on the domain you're modelling. In answer to your question, the first method adds the fewest additional elements to the schema.

Elixir recursion

I have a group, which I can attach to other modules. The group can have a parent group:
schema "groups" do
field :name, :string
field :deleted, :boolean
belongs_to :parent, Group
has_many :users_groups, UserGroup, foreign_key: :group_id
timestamps()
end
Via user_groups i Can attach users. Now I want to filter, if the user is allowed to see the attached module. I made a check, to see if the user is inside the attached group:
def get_visible_module(module, user_id) do
case module.group do
nil -> module
_ ->
case module.group.users_groups do
nil -> module
_ ->
val = Enum.filter(module.group.users_groups, fn(x)->
x.user_id == user_id
end)
case val do
[] ->
case false do
true -> module
false -> nil
end
_ -> module
end
end
end
end
This may be not the best code, but I am still learning, so improvements to this part are also welcome :)
Now my problem is to add a recursion to check, if the user_id is attached via user_group to a group, which is attached via the parent_id. I am stucked at this point. For the understanding: A module has a group attached. Only the user in the group or in the group attached via parent_id are allowed to see the module. Groups are structered as a tree, so I need to eager load the parent group and check if the user_group contains the user and check every parent-group too.
Hope it is understandable.
THX
Here is a rough skeleton which adapts the naming of your source code. It should give you an idea on how to make a recursion in elixir.
# Exit case when a module has no more parent
def get_visible_module(module, nil, user_id) do
user_in_groups?(module.group.users_groups, user_id)
end
# Case when the module has a parent_id
def get_visible_module(module, parent_id, user_id) do
# check the groups for user_id permission followed by the recusive part
user_in_groups?(module.group.users_groups, user_id) and get_visible_module(parent_module, parent_module.parent_id, user_id)
end
# checks if the user is in the group
defp user_in_groups?(users_groups, user_id) do
# check if the use is in one of the groups
true
end
As #bla already mentioned you should try to use pattern matching to clean up your code and reduce the nesting level of your code.

How can I order by NULL in DQL?

I'm building an app using Symfony2 framework and using Doctrine ORM. I have a table with airlines for which some IATA codes are missing. I'm outputting a list, ordered by this IATA code, but I'm getting the undesirable result that the records with null IATA codes are sorted at the top.
In MySQL this is simple enough to do, with ORDER BY ISNULL(code_iata), code_iata but I'm clueless as to what the equivalent would be for DQL. I tried
$er->createQueryBuilder('airline')->orderBy('ISNULL(airline.codeIata), airline.codeIata', 'ASC')
but this gives me a syntax error.
The Doctrine docs give me no answer either. Is there a way?
You can use the following trick in DQL to order NULL values last
$em->createQuery("SELECT c, -c.weight AS HIDDEN inverseWeight FROM Entity\Car c ORDER BY inverseWeight DESC");
The HIDDEN keyword (available since Doctrine 2.2) will result in omitting the inverseWeight field from the result set and thus preventing undesirable mixed results.
(The sort fields value is inverted therefore the order has to be inverted too, that's why the query uses DESC order, not ASC.)
Credits belong to this answer.
The most unobtrusive generic solution would be to use the CASE expression in combination with the HIDDEN keyword.
SELECT e,
CASE WHEN e.field IS NULL THEN 1 ELSE 0 END HIDDEN _isFieldNull
FROM FooBundle:Entity e
ORDER BY _isFieldNull ASC
Works with both numeric as well as other field types and doesn't require extending Doctrine.
If you want to do something similar to "NULLS LAST" in SQL (with PostgreSQL in my case):
ORDER BY freq DESC NULLS LAST
You can use the COALESCE function with the Doctrine Query Builder
(HIDDEN will hide the field "freq" on your query result set).
$qb = $this->createQueryBuilder('d')
->addSelect('COALESCE(d.freq, 0) AS HIDDEN freq')
->orderBy('freq', 'DESC')
->setMaxResults(20);
Here it is an example for a custom walker to get exactly what you want. I have taken it from Doctrine in its github issues:
https://github.com/doctrine/doctrine2/pull/100
But the code as it is there didn't work for me in MySQL. I have modified it to work in MySQL, but I haven't test at all for other engines.
Put following walker class for example in YourNS\Doctrine\Waler\ directory;
<?php
namespace YourNS\Doctrine\Walker;
use Doctrine\ORM\Query\SqlWalker;
class SortableNullsWalker extends SqlWalker
{
const NULLS_FIRST = 'NULLS FIRST';
const NULLS_LAST = 'NULLS LAST';
public function walkOrderByClause($orderByClause)
{
$sql = parent::walkOrderByClause($orderByClause);
if ($nullFields = $this->getQuery()->getHint('SortableNullsWalker.fields'))
{
if (is_array($nullFields))
{
$platform = $this->getConnection()->getDatabasePlatform()->getName();
switch ($platform)
{
case 'mysql':
// for mysql the nulls last is represented with - before the field name
foreach ($nullFields as $field => $sorting)
{
/**
* NULLs are considered lower than any non-NULL value,
* except if a – (minus) character is added before
* the column name and ASC is changed to DESC, or DESC to ASC;
* this minus-before-column-name feature seems undocumented.
*/
if ('NULLS LAST' === $sorting)
{
$sql = preg_replace_callback('/ORDER BY (.+)'.'('.$field.') (ASC|DESC)/i', function($matches) {
if ($matches[3] === 'ASC') {
$order = 'DESC';
} elseif ($matches[3] === 'DESC') {
$order = 'ASC';
}
return ('ORDER BY -'.$matches[1].$matches[2].' '.$order);
}, $sql);
}
}
break;
case 'oracle':
case 'postgresql':
foreach ($nullFields as $field => $sorting)
{
$sql = preg_replace('/(\.' . $field . ') (ASC|DESC)?\s*/i', "$1 $2 " . $sorting, $sql);
}
break;
default:
// I don't know for other supported platforms.
break;
}
}
}
return $sql;
}
}
Then:
use YourNS\Doctrine\Walker\SortableNullsWalker;
use Doctrine\ORM\Query;
[...]
$qb = $em->getRepository('YourNS:YourEntity')->createQueryBuilder('e');
$qb
->orderBy('e.orderField')
;
$entities = $qb->getQuery()
->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, '\YourNS\Doctrine\Walker\SortableNullsWalker')
->setHint('SortableNullsWalker.fields', array(
'sortOrder' => SortableNullsWalker::NULLS_LAST
))
->getResult();
DQL does not contain every function of plain SQL. Fortunately you can define your custom DQL method to accomplish this.
Some resources:
http://punkave.com/window/2012/07/24/for-the-php-crowd-adding-custom-functions-to-doctrine-2-dql
http://docs.doctrine-project.org/en/2.1/cookbook/dql-user-defined-functions.html
http://symfony.com/doc/2.0/cookbook/doctrine/custom_dql_functions.html
By default, MySQL will still sort a NULL value; it will just place it at the beginning of the result set if it was sorted ASC, and at the end if it was sorted DESC. Here, you're looking to sort ASC, but you want the NULL values to be at the bottom.
Unfortunately, as powerful as it is, Doctrine isn't going to offer much support here, since function support is limited, and most of it is limited to SELECT, WHERE, and HAVING clauses. You actually wouldn't have a problem at all if any of the following were true about the QueryBuilder:
select() accepted ISNULL()
orderBy() or addOrderBy() supported ISNULL()
the class supported the concept of UNIONs (with this, you could run two queries: one where the codeIata was NULL, and one where it wasn't, and you could sort each independently)
So that said, you can go with the user-defined functions that ArtWorkAD mentioned already, or you could replicate that last point with two different Doctrine queries:
$airlinesWithCode = $er->createQueryBuilder("airline")
->where("airline.iataCode IS NULL")
->getQuery()
->getResult();
$airlinesWithoutCode = $er->createQueryBuilder("airline")
->where("airline.iataCode IS NOT NULL")
->getQuery()
->getResult();
Then you can combine these into a single array, or treat them independently in your templates.
Another idea is to have DQL return everything in one data set, and let PHP do the heavy lifting. Something like:
$airlines = $er->findAll();
$sortedAirlines = array();
// Add non-NULL values to the end if the sorted array
foreach ($airlines as $airline)
if ($airline->getCodeIata())
$sortedAirlines[] = $airline;
// Add NULL values to the end of the sorted array
foreach ($airlines as $airline)
if (!$airline->getCodeIata())
$sortedAirlines[] = $airline;
The downside to both of these is that you won't be able to do LIMITs in MySQL, so it might only work well for relatively small data sets.
Anyway, hope this gets you on your way!

LINQ - 'Could not translate expression' with previously used and proven query condition

I am fairly new to LINQ and can't get my head around some inconsistency in behaviour. Any knowledgeable input would be much appreciated. I see similar issues on SO and elsewhere but they don't seem to help.
I have a very simple setup - a company table and an addresses table. Each company can have 0 or more addresses, and if > 0 one must be specified as the main address. I'm trying to handle the cases where there are 0 addresses, using an outer join and altering the select statement accordingly.
Please note I'm currently binding the output straight to a GridView so I would like to keep all processing within the query.
The following DOES work
IQueryable query =
from comp in context.Companies
join addr in context.Addresses on comp.CompanyID equals addr.CompanyID into outer // outer join companies to addresses table to include companies with no address
from addr in outer.DefaultIfEmpty()
where (addr.IsMain == null ? true : addr.IsMain) == true // if a company has no address ensure it is not ruled out by the IsMain condition - default to true if null
select new {
comp.CompanyID,
comp.Name,
AddressID = (addr.AddressID == null ? -1 : addr.AddressID), // use -1 to represent a company that has no addresses
MainAddress = String.Format("{0}, {1}, {2} {3} ({4})", addr.Address1, addr.City, addr.Region, addr.PostalCode, addr.Country)
};
but this displays an empty address in the GridView as ", , ()"
So I updated the MainAddress field to be
MainAddress = (addr.AddressID == null ? "" : String.Format("{0}, {1}, {2} {3} ({4})", addr.Address1, addr.City, addr.Region, addr.PostalCode, addr.Country))
and now I'm getting the Could not translate expression error and a bunch of spewey auto-generated code in the error which means very little to me.
The condition I added to MainAddress is no different to the working condition on AddressID, so can anybody tell me what's going on here?
Any help is greatly appreciated.
The error you are getting is telling you that LinqToSql cannot translate your null check and then string.Format expression into SQL. If you look at the SQL your first query is generating (using either LinqPad or SQL Profiler), you'll see something like:
SELECT [t0].[CompanyID], [t0].[Name],
(CASE
WHEN [t1].[AddressID] IS NULL THEN #p0
ELSE [t1].[AddressID]
END) AS [AddressID],
[t1].[Address1] AS [value],
[t1].[City] AS [value2],
[t1].[Region] AS [value3],
[t1].[PostalCode] AS [value4],
[t1].[Country] AS [value5]
FROM [Company] AS [t0]
LEFT OUTER JOIN [Address] AS [t1] ON [t0].[CompanyID] = [t1].[CompanyID]
WHERE ([t1].[IsMain] IS NULL) OR ([t1].[IsMain] = 1)
For your AddressID field, you can see that it uses a CASE-WHEN to handle the condition when AddressID is null. When you add a CASE-WHEN for MainAddress, it's trying to do the same thing for that field, but there is no SQL equivalent to string.Format it can use for the ELSE clause, so it blows up.
An easy way around this problem is to use a method to format the string. By calling a private method, LinqToSql won't try to translate the string.Format to SQL, and will instead return all of the fields necessary to populate the Address object. The method can then take care of the formatting.
For example:
LINQ:
....
select new {
comp.CompanyID,
comp.Name,
AddressID = (addr.AddressID == null ? -1 : addr.AddressID),
MainAddress = FormatAddress(addr)
};
Method:
private static string FormatAddress(Address addr)
{
return (addr == null ? "" :
string.Format("{0}, {1}, {2} {3} ({4})",
addr.Address1, addr.City,
addr.Region, addr.PostalCode, addr.Country));
}

Resources