Supabase `and` in the `or` query - supabase

How would I construct this filter in a select statement (I am using dart)
(senttouid = userid or (uid=userid and parent is true))
we have the or({}) construct, which AFAIK will support the senttouid = userid or uid=userid filter, but not if the second part of 'or' has a compound filter
Using a stored procedure seems to be the way to go, but is there a direct way to construct this in the dart query?

Related

Create a Dynamic Entity Framework Where Query

At runtime I have a dynamic list of "Parent" ids i need to query against one of my entity tables, using LINQ how would I generate the query at run time? Currently am (VERY SLOWLY) looping over my list of ID's and performing a separate query to the database using the Where method. Is there an API that will allow me to build a single WHERE statement that in essence is appending "&& value = something" as I would have if I was writing the SQL myself?
Currently what i do looks like this
foreach(var parent in parents)
{
col.AddRange(context.LocalAuthorities.Where(c => c.Parent.ID == parent.ID).ToList());
}
If your goal is to replace multiple iterative queries by one query, you can use this approach:
var allParentIds = parents.Select(p=>p.ID).ToList();
var result = context.LocalAuthorities.Where(c=> allParentIds.Contains(c.Parent.ID));
col.AddRange(result);

ActiveRecord Subquery Inner Join

I am trying to convert a "raw" PostGIS SQL query into a Rails ActiveRecord query. My goal is to convert two sequential ActiveRecord queries (each taking ~1ms) into a single ActiveRecord query taking (~1ms). Using the SQL below with ActiveRecord::Base.connection.execute I was able to validate the reduction in time.
Thus, my direct request is to help me to convert this query into an ActiveRecord query (and the best way to execute it).
SELECT COUNT(*)
FROM "users"
INNER JOIN (
SELECT "centroid"
FROM "zip_caches"
WHERE "zip_caches"."postalcode" = '<postalcode>'
) AS "sub" ON ST_Intersects("users"."vendor_coverage", "sub"."centroid")
WHERE "users"."active" = 1;
NOTE that the value <postalcode> is the only variable data in this query. Obviously, there are two models here User and ZipCache. User has no direct relation to ZipCache.
The current two step ActiveRecord query looks like this.
zip = ZipCache.select(:centroid).where(postalcode: '<postalcode>').limit(1).first
User.where{st_intersects(vendor_coverage, zip.centroid)}.count
Disclamer: I've never used PostGIS
First in your final request, it seems like you've missed the WHERE "users"."active" = 1; part.
Here is what I'd do:
First add a active scope on user (for reusability)
scope :active, -> { User.where(active: 1) }
Then for the actual query, You can have the sub query without executing it and use it in a joins on the User model, such as:
subquery = ZipCache.select(:centroid).where(postalcode: '<postalcode>')
User.active
.joins("INNER JOIN (#{subquery.to_sql}) sub ON ST_Intersects(users.vendor_coverage, sub.centroid)")
.count
This allow minimal raw SQL, while keeping only one query.
In any case, check the actual sql request in your console/log by setting the logger level to debug.
The amazing tool scuttle.io is perfect for converting these sorts of queries:
User.select(Arel.star.count).where(User.arel_table[:active].eq(1)).joins(
User.arel_table.join(ZipCach.arel_table).on(
Arel::Nodes::NamedFunction.new(
'ST_Intersects', [
User.arel_table[:vendor_coverage], Sub.arel_table[:centroid]
]
)
).join_sources
)

How do I insert a native Oracle call or cast (to NVARCHAR2) in a criteria api expression?

I have a complex dynamic query in Eclipselink with a case expression that involves two different columns, one of VARCHAR2 and one of NVARCHAR2.
It needs to be a case expression, because I also want to be able to sort by that result column, so I can't just query both. In Java, both are just mapped as a String, so you don't even see there's a difference.
For my query, Eclipselink creates the following select expression:
CASE
WHEN (t9.STRINGVALUE IS NOT NULL)
THEN t9.STRINGVALUE
ELSE t10.OTHERSTRINGVALUE
END ,
The criteria code is:
Expression<String> str = firstRoot.get("stringValue");
Expression<String> strExp = cb.<String> selectCase().when(cb.isNotNull(str), str)
.otherwise(otherRoot.<String> get("otherStringValue"));
q.multiselect(..., strExp, ...);
which causes Oracle to fail with ORA-12704: character set mismatch. I'd like to modify the code to result in
cast(t10.OTHERSTRINGVALUE as NVARCHAR2(50),
but I cannot find out how.
I tried a converter on the Entity's field, or a .as(String.class) on the .get()-expressions for both fields.
So the question: is there a way to pass an Oracle type like NVARCHAR2 to the .as() expression? Can I otherwise insert a call to CAST(... as NVARCHAR2) with criteria API? Is there any other way to have it generate custom SQL, because I REALLY cannot rewrite the whole query, just because JPA or EL don't provide for the possibility that you might need some custom SQL...
The only way to do it in criteria API is to create a new PathImpl from the otherRoot. get("otherStringValue") path, passing in an EclipseLink native cast expression as the expression node. something like:
PathImpl path = (PathImpl)otherRoot.<String> get("otherStringValue");
Path castPath = new PathImpl(path, em.getMetamodel(), path.getJavaType(), path.getCurrentNode().cast("NVARCHAR2"), path.getModel());
Expression<String> str = firstRoot.get("stringValue");
Expression<String> strExp = cb.<String> selectCase().when(cb.isNotNull(str), str)
.otherwise(castPath );
q.multiselect(..., strExp, ...);

Is this linq query efficient?

Is this linq query efficient?
var qry = ((from member in this.ObjectContext.TreeMembers.Where(m => m.UserId == userId && m.Birthdate == null)
select member.TreeMemberId).Except(from item in this.ObjectContext.FamilyEvents select item.TreeMemberId));
var mainQry = from mainMember in this.ObjectContext.TreeMembers
where qry.Contains(mainMember.TreeMemberId)
select mainMember;
Will this be translated into multiple sql calls or just one? Can it be optimised? Basically I have 2 tables, I want to select those records from table1 where datetime is null and that record should not exist in table2.
The easiest way to find out if the query will make multiple calls is to set the .Log property of the data context. I typically set it to write to a DebugOutputWriter. A good example for this kind of class can be found here.
For a general way of thinking about it however, if you use a property of your class that does not directly map to a database field in a where clause or a join clause, it will typically make multiple calls. From what you have provided, it looks like this is not the case for your scenario, but I can't absolutely certain and suggest using the method listed above.

How to create a dynamic linq query for filter based on ria service?

Suppose I have a table Person(PersonID, Name, ....). Then I use EF to create a Entity model and then create DomainService based on Ria Service. At client side(sliverlight), I try to create a dynamic linq for filter function. What I did is:
q = EntityQuery<MyData.Person>
q = q.Where(p=> p.Name.Contains(NameVar));
That is fine. Then I have another two tables for phone:
Phone(PhoneID, PhoneNumber, ...)
PersonPhone(PersonID, PhoneID, ...)
Then I want to add filter to match PhoneNumber. How to write the linq query q like?
q = q.Where(p => p.PersonPhone.
Where(ph=>ph.PhoneNumber.Contains(PhoneVar)&& ph.PersonID == p.PersonID).Count()>0);
I can pass the compiliation, but when run the app, I got error:
Query operator 'Count' is not supported
How to resolve this problem?
This sounds like a good scenario for writing a custom query method on the server and invoking that method instead of the default query for Person. RIA Services only supports a subset of LINQ operations on the client, but you can use all LINQ operators on the server.
You need to use the QueryBuilder
Here's a sample
var qb = new QueryBuilder<Person>().Where(p => p.PersonPhone.Where(ph=>ph.PhoneNumber.Contains(PhoneVar)&& ph.PersonID == p.PersonID).Count()>0);
Then you can take qb and apply it to whatever query you like.
query = qb.ApplyTo(query);
By using Func<QueryBuilder<Person>> you can pass around your dynamic filter into common controls and etc. And when you invoke the function you'll get the current values from that ViewModel.

Resources