- From: Andy Seaborne <andy.seaborne@talis.com>
- Date: Sun, 29 Nov 2009 21:37:44 +0000
- To: RDF Data Access Working Group <public-rdf-dawg@w3.org>
LeeF asked (a couple of week ago now) about the equivalence of SELECT expressions and LET (assignment) as syntax forms. Here is a description of translations from SELECT expr to LET and from LET to SELECT expr. Andy == SELECT to LET We are translating SELECT (?a+1 AS ?b), ?c, (?d+1 AS ?e) { pattern } => This follows the algebra translation but generates synatx, not algebra expressions. ---- Step SL-1: Split into two lists, expressions and projections. [] for lists. AS-Expressions [(?b, ?a+1) , (?e, ?d+1)] Projection: [?b, ?c, ?e] ----- To get a LET apply the following: Step SL-2: Generate the projection-only SELECT, from the original projected variables and the AS variables. "SELECT ?b ?c ?e" Step SL-3: Generate the SELECT WHERE clause, up to the "}" """ SELECT ?b, ?c, ?e { pattern """ Step SL-4: Insert LET For each AS-expression (var, expr) Generate "LET(?var := expr)" Step SL-5: Generate "}" so that gives: """ SELECT ?b, ?c, ?e { pattern LET (?b := ?a+1) LET (?e := ?d+1) } """ The order of the projection is preserved. == LET to SELECT (part 1) We first look at a simple case: { pattern LET (?b := ?a+1) LET (?e := ?d+1) } Step LS-1-1: Split into: The WHERE part: pattern Any assignments: (?b, ?a+1) (?e, ?d+1) Determine variables used in pattern (same as SELECT * { Pattern }) We use VAR(pattern) here for that. Step LS-1-2: Generate "SELECT VAR(pattern)" Step LS-1-3: For each assignment Generate "(" expr "AS" var ")" SELECT VAR(pattern) (?a+1 AS ?b) (?d+1 AS ?e) Step LS-1-4: Generate { pattern } giving """ SELECT VAR(pattern) (?a+1 AS ?b) (?d+1 AS ?e) { pattern } == LET to SELECT (part 2) The general case is: { pattern1 LET (?b := ?a+1) pattern2 LET (?e := ?d+1) pattern3 } Informally, this will become: { { { pattern1 LET (?b := ?a+1) } pattern2 LET (?e := ?d+1) } pattern3 } where the part 1 steps applied at each pattern boundary. Algorithmically: Set P = empty pattern Set X = [], the empty list. -- First LET: At LET (?b := ?a+1) do the following: Append VARS(pattern1) to X Generate a SELECT clause with the projection variables from X and the assignment written as AS Generate pattern1, in {} "SELECT X1 (?a+1 AS ?b) { pattern1 } " where X1 is the value of list X at this point. Assign this to P Append "?b" to X -- Second LET: At LET (?e := ?d+1) do the following: Append VARS(pattern2) to X Generate a SELECT clause with the projection variables from X and the assignment written as AS Start { Generate P as a nested SELECT Generate pattern2 End } """ SELECT X2 (?d+1 AS ?e) { { SELECT X1 (?a+1 AS ?b) { pattern1 } } pattern2 } """ where X2 is the value of X at this point. Assign this to P Append "?e" to X -- End of {} Append VARS(pattern3) to X Generate a SELECT clause with the projection variables from X and the assignment written as AS Start { Generate P as a nested SELECT Generate pattern3 End } """ SELECT X3 { { SELECT X2 (?d+1 AS ?e) { { SELECT X1 (?a+1 AS ?b) { pattern1 } } pattern2 } } pattern3 } """ Notes: 1 -- The "First LET" step can be the same as the rest by generating a subselect on the empty pattern because { SELECT * {} } is the join identity. 2 -- pattern2 can use ?b; pattern3 can use ?b and ?e 3 -- LETs end BGPs. Scope is maintained by using subSELECTs
Received on Sunday, 29 November 2009 21:38:19 UTC