Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multivalued query params #161

Open
VladimirAlexiev opened this issue Jun 15, 2022 · 3 comments
Open

Multivalued query params #161

VladimirAlexiev opened this issue Jun 15, 2022 · 3 comments

Comments

@VladimirAlexiev
Copy link
Contributor

VladimirAlexiev commented Jun 15, 2022

First see #57.

Why?

In a current project on company data, there's need for multivalued query parameters. Eg

?company :country ?country
filter(?country in ($countries))

or

values ?country {$countries}
?company :country ?country

Hopefully a good SPARQL endpoint will implement both cases above in the same way, and order the patterns efficiently. But:

  • there's no way to bind a HTTP param $var to multiple values
  • the form of param serialization depends on the selected case: comma-separated in in, space-separated in values

If you need several correlated params, maybe parallel values can be used:

values (?region ?country) {($regions $countries)}
?company :region ?region; :country ?country

or something like this, using a list of pairs

values (?region ?country) {$regions_countries}

Previous work

None of the query parameterization prior art has a concept of multivalued query params.

  • Basil's convention can mark optional params, but not multivalued
  • WD can issue a subsidiary query to populate a param, and that could return multiple values. But that subsidiary is run first and not related to the main query. It's better to decouple the two queries because there may be need for some manipulation to be done to the results, and leave "query threading" to be done with a program

Example of "query threading":

  • find $companies that satisfy some criterion; allow the user to select a subset of them
  • find all their industry $sectors; allow the user to select a subset of them
  • find all $subindustries of the selected companies in the selected sectors; allow the user to select a subset of them
  • run a complex query using $companies, $sectors, $subsectors that fetches further data. These are multivalued params that are correlated in a complex way (not just with parallel values)

Proposal

I don't feel qualified to make a coherent proposal, but here are some ideas:

  • Extend the $var notation to allow indicating a multivalued param
  • Add some syntax to indicate syntactic processing of such param. For example (but I'm sure there are better ways to say that)
filter(?country in (EXPAND_COMMA_SEP($countries)))
values ?country {EXPAND_SPACE_SEP($countries)}
values (?region ?country) {EXPAND_TUPLES($regions_countries)}

Backward compatibility

  • As answered in Query Parameterization #57, we can't mandate that $ is used for an externally bound var
  • And adding further syntax as above may have worse Backward compatibility implications

So I'm looking for ideas and best practices, more than anything else.

@lisp
Copy link
Contributor

lisp commented Apr 11, 2023

one example of a way to support multivalued parameters is to recognize arbitrary values data blocks as parameters and bind them to the locations in the query which have matching variables.
an example is

https://github.com/dydra/http-api-tests/blob/master/extensions/sparql-protocol/values/inline-query-multiple.sh

it is tedious, but all the aspects seem necessary.

curl_sparql_request \
  "--data-urlencode" "query@/dev/fd/3" \
  "--data-urlencode" "values@/dev/fd/4" \
  "--data-urlencode" "values@/dev/fd/5" \
  -H "Content-Type: application/x-www-form-urlencoded"  3<<EOF3  4<<EOF4 5<<EOF5 \
 | jq '.results.bindings[] | .[].value' |  tr '\n' ' ' | fgrep "blue" | fgrep -q "BSS84"
select ?value1 ?value2
where { 
 values (?name ?value1) {} 
 values (?name ?value2) {} 
}
EOF3
(?name ?value1) { (<http://example.org/one> 'BUK7Y98-80E')
                  (<http://example.org/two> 'PH3330L')
                  (<http://example.org/three> 'BSS84') }
EOF4
(?name ?value2) { (<http://example.org/one> 'red')
                  (<http://example.org/two> 'green')
                  (<http://example.org/three> 'blue') }
EOF5

@VladimirAlexiev
Copy link
Contributor Author

VladimirAlexiev commented May 17, 2023

@lisp

  • This is some advanced shell hackery, great! :-)
  • So, you pass ?values POST param multiple times, and each is the complete text of a VALUES block that's matched by all mentioned variables. I like this!
    @afs, @ericprud, @kasei, @JervenBolleman, @abrokenjester what do you think?
  • Let's see how the existing notation would map to this:
# EXISTING:
## query
$var
## http param:
$var=<http://example.org/one>

# NEWLY PROPOSED:
## query
values $var {}
...
$var
## http param:
values=($var) {<http://example.org/one>}

@lisp
Copy link
Contributor

lisp commented May 17, 2023

  • So, you pass ?values POST param multiple times, and each is the complete text of a VALUES block that's matched by all mentioned variables. I like this!

-> every values block - there can be more than one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants