@traqula/rules-sparql-1-2 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { getAggregatesOfExpression, getExpressionId, getVariablesFromExpression } from '@traqula/rules-sparql-1-1';
1
2
  import { AstFactory } from './AstFactory.js';
2
3
  const F = new AstFactory();
3
4
  function isLangDir(dir) {
@@ -92,4 +93,77 @@ export function findPatternBoundedVars(iter, boundedVars) {
92
93
  }
93
94
  }
94
95
  }
96
+ /**
97
+ * Verify that the projected variables (select head) are allowed:
98
+ * - no group-by on select *
99
+ * - if group-by, selected variables need to be collected by the group-by
100
+ * - 'select ?var as ?other', ?other cannot be in scope
101
+ */
102
+ export function queryProjectionIsGood(query) {
103
+ // NoGroupByOnWildcardSelect
104
+ if (query.variables.length === 1 && F.isWildcard(query.variables[0])) {
105
+ if (query.solutionModifiers.group !== undefined) {
106
+ throw new Error('GROUP BY not allowed with wildcard');
107
+ }
108
+ return;
109
+ }
110
+ // CannotProjectUngroupedVars - can be skipped if `SELECT *`
111
+ // Check for projection of ungrouped variable
112
+ // Check can be skipped in case of wildcard select.
113
+ const variables = query.variables;
114
+ const hasCountAggregate = variables.flatMap(varVal => F.isTerm(varVal) ? [] : getAggregatesOfExpression(varVal.expression)).some(agg => agg.aggregation === 'count' && !agg.expression.some(arg => F.isWildcard(arg)));
115
+ const groupBy = query.solutionModifiers.group;
116
+ if (hasCountAggregate || groupBy) {
117
+ // We have to check whether
118
+ // 1. Variables used in projection are usable given the group by clause
119
+ // 2. A selectCount will create an implicit group by clause.
120
+ // Variables bound by preceding (expr AS ?var) expressions are in scope for later expressions.
121
+ const asBoundVars = new Set();
122
+ for (const selectVar of variables) {
123
+ if (F.isTerm(selectVar)) {
124
+ if (!groupBy || !groupBy.groupings.map(groupvar => getExpressionId(groupvar))
125
+ .includes((getExpressionId(selectVar)))) {
126
+ throw new Error('Variable not allowed in projection');
127
+ }
128
+ }
129
+ else if (getAggregatesOfExpression(selectVar.expression).length === 0) {
130
+ // Current value binding does not use aggregates
131
+ const usedvars = new Set();
132
+ getVariablesFromExpression(selectVar.expression, usedvars);
133
+ for (const usedvar of usedvars) {
134
+ // If the var is created within the select, it is fine.
135
+ if (asBoundVars.has(usedvar)) {
136
+ continue;
137
+ }
138
+ if (!groupBy || !groupBy.groupings.map(groupVar => getExpressionId(groupVar)).includes(usedvar)) {
139
+ throw new Error(`Use of ungrouped variable in projection of operation (?${usedvar})`);
140
+ }
141
+ }
142
+ }
143
+ if (!F.isTerm(selectVar)) {
144
+ // Register a var is created by a bind
145
+ asBoundVars.add(selectVar.variable.value);
146
+ }
147
+ }
148
+ }
149
+ // NOTE 12: Check if id of each AS-selected column is not yet bound by subquery
150
+ const subqueries = query.where.patterns.filter(pattern => pattern.type === 'query');
151
+ if (subqueries.length > 0) {
152
+ const selectBoundedVars = new Set();
153
+ for (const variable of variables) {
154
+ if ('variable' in variable) {
155
+ selectBoundedVars.add(variable.variable.value);
156
+ }
157
+ }
158
+ // Look at in scope variables
159
+ const vars = subqueries.flatMap(sub => sub.variables)
160
+ .map(v => F.isTerm(v) ? v.value : (F.isWildcard(v) ? '*' : v.variable.value));
161
+ const subqueryIds = new Set(vars);
162
+ for (const selectedVarId of selectBoundedVars) {
163
+ if (subqueryIds.has(selectedVarId)) {
164
+ throw new Error(`Target id of 'AS' (?${selectedVarId}) already used in subquery`);
165
+ }
166
+ }
167
+ }
168
+ }
95
169
  //# sourceMappingURL=validators.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../lib/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAY7C,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;AAE3B,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAoB;IACzD,IAAI,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,CAAE,CAAC,EAAE,SAAS,CAAE,GAAG,QAAQ,CAAC;YAClC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,uBAAuB,SAAS,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC;YACvI,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,IAAuF,EACvF,WAAwB;IAExB,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,sBAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC/B,sBAAsB,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;gBACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;gBAC9C,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;oBACnC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;wBACpB,sBAAsB,CAAC,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;oBAClD,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;gBAClC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,sBAAsB,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAClD,sBAAsB,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YACpD,sBAAsB,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,sBAAsB,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAClD,sBAAsB,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACpD,sBAAsB,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACjD,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YAChD,sBAAsB,CACpB,CAAC,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAC9D,WAAW,CACZ,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,sBAAsB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,sBAAsB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;SAAM,IACL,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5G,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,sBAAsB,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,sBAAsB,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC5D,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,sBAAsB,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC/C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { AstFactory } from './AstFactory.js';\nimport type {\n Path,\n Pattern,\n SparqlQuery,\n Term,\n TermLiteral,\n TripleCollection,\n TripleNesting,\n Wildcard,\n} from './sparql12Types.js';\n\nconst F = new AstFactory();\n\nfunction isLangDir(dir: string): dir is 'ltr' | 'rtl' {\n return dir === 'ltr' || dir === 'rtl';\n}\n\nexport function langTagHasCorrectRange(literal: TermLiteral): void {\n if (F.isTermLiteralLangStr(literal)) {\n const dirSplit = literal.langOrIri.split('--');\n if (dirSplit.length > 1) {\n const [ _, direction ] = dirSplit;\n if (!isLangDir(direction)) {\n throw new Error(`language direction \"${direction}\" of literal \"${JSON.stringify(literal)}\" is not is required range 'ltr' | 'rtl'.`);\n }\n }\n }\n}\n\nexport function findPatternBoundedVars(\n iter: SparqlQuery | Pattern | TripleNesting | TripleCollection | Path | Term | Wildcard,\n boundedVars: Set<string>,\n): void {\n if (F.isQuery(iter) || F.isUpdate(iter)) {\n if (F.isQuerySelect(iter) || F.isQueryDescribe(iter)) {\n if (iter.where && iter.variables.some(x => F.isWildcard(x))) {\n findPatternBoundedVars(iter.where, boundedVars);\n } else {\n for (const v of iter.variables) {\n findPatternBoundedVars(v, boundedVars);\n }\n }\n if (iter.solutionModifiers.group) {\n const grouping = iter.solutionModifiers.group;\n for (const g of grouping.groupings) {\n if ('variable' in g) {\n findPatternBoundedVars(g.variable, boundedVars);\n }\n }\n }\n if (iter.values?.values && iter.values.values.length > 0) {\n const values = iter.values.values;\n for (const v of Object.keys(values[0])) {\n boundedVars.add(v);\n }\n }\n }\n } else if (F.isTerm(iter)) {\n if (F.isTermVariable(iter)) {\n boundedVars.add(iter.value);\n }\n if (F.isTermTriple(iter)) {\n findPatternBoundedVars(iter.subject, boundedVars);\n findPatternBoundedVars(iter.predicate, boundedVars);\n findPatternBoundedVars(iter.object, boundedVars);\n }\n } else if (F.isTriple(iter)) {\n findPatternBoundedVars(iter.subject, boundedVars);\n findPatternBoundedVars(iter.predicate, boundedVars);\n findPatternBoundedVars(iter.object, boundedVars);\n for (const annotation of iter.annotations ?? []) {\n findPatternBoundedVars(\n F.isTripleCollection(annotation) ? annotation : annotation.val,\n boundedVars,\n );\n }\n } else if (F.isPath(iter)) {\n for (const item of iter.items) {\n findPatternBoundedVars(item, boundedVars);\n }\n } else if (F.isTripleCollection(iter) || F.isPatternBgp(iter)) {\n for (const triple of iter.triples) {\n findPatternBoundedVars(triple, boundedVars);\n }\n } else if (\n F.isPatternGroup(iter) || F.isPatternUnion(iter) || F.isPatternOptional(iter) || F.isPatternService(iter)) {\n for (const pattern of iter.patterns) {\n findPatternBoundedVars(pattern, boundedVars);\n }\n if (F.isPatternService(iter)) {\n findPatternBoundedVars(iter.name, boundedVars);\n }\n } else if (F.isPatternBind(iter)) {\n findPatternBoundedVars(iter.variable, boundedVars);\n } else if (F.isPatternValues(iter)) {\n for (const variable of Object.keys(iter.values.at(0) ?? {})) {\n boundedVars.add(variable);\n }\n } else if (F.isPatternGraph(iter)) {\n findPatternBoundedVars(iter.name, boundedVars);\n for (const pattern of iter.patterns) {\n findPatternBoundedVars(pattern, boundedVars);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../lib/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAEnH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAe7C,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;AAE3B,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAoB;IACzD,IAAI,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,CAAE,CAAC,EAAE,SAAS,CAAE,GAAG,QAAQ,CAAC;YAClC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,uBAAuB,SAAS,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC;YACvI,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,IAAuF,EACvF,WAAwB;IAExB,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,sBAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC/B,sBAAsB,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;gBACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;gBAC9C,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;oBACnC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;wBACpB,sBAAsB,CAAC,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;oBAClD,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;gBAClC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,sBAAsB,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAClD,sBAAsB,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YACpD,sBAAsB,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,sBAAsB,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAClD,sBAAsB,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACpD,sBAAsB,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACjD,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YAChD,sBAAsB,CACpB,CAAC,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAC9D,WAAW,CACZ,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,sBAAsB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,sBAAsB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;SAAM,IACL,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5G,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,sBAAsB,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,sBAAsB,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC5D,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,sBAAsB,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC/C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAqE;IACzG,4BAA4B;IAC5B,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,IAAI,KAAK,CAAC,iBAAiB,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QACD,OAAO;IACT,CAAC;IAED,4DAA4D;IAC5D,6CAA6C;IAC7C,mDAAmD;IACnD,MAAM,SAAS,GAAiD,KAAK,CAAC,SAAS,CAAC;IAChF,MAAM,iBAAiB,GAAG,SAAS,CAAC,OAAO,CACzC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,yBAAyB,CAAkB,MAAM,CAAC,UAAU,CAAC,CAChG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,OAAO,GAAG,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC;IAC9C,IAAI,iBAAiB,IAAI,OAAO,EAAE,CAAC;QACjC,2BAA2B;QAC3B,wEAAwE;QACxE,6DAA6D;QAC7D,8FAA8F;QAC9F,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;QACtC,KAAK,MAAM,SAAS,IAAI,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAChD,eAAe,CAAkD,QAAQ,CAAC,CAAC;qBAC1E,QAAQ,CAAC,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1C,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC;iBAAM,IAAI,yBAAyB,CAAkB,SAAS,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzF,gDAAgD;gBAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;gBACnC,0BAA0B,CAAkB,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;gBAC5E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,uDAAuD;oBACvD,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC7B,SAAS;oBACX,CAAC;oBACD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAChD,eAAe,CAAiD,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC/F,MAAM,IAAI,KAAK,CAAC,0DAA0D,OAAO,GAAG,CAAC,CAAC;oBACxF,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzB,sCAAsC;gBACtC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;IACpF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC5C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,UAAU,IAAI,QAAQ,EAAE,CAAC;gBAC3B,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAwC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;aACzF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAChF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,KAAK,MAAM,aAAa,IAAI,iBAAiB,EAAE,CAAC;YAC9C,IAAI,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,uBAAuB,aAAa,4BAA4B,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { getAggregatesOfExpression, getExpressionId, getVariablesFromExpression } from '@traqula/rules-sparql-1-1';\nimport type * as T11 from '@traqula/rules-sparql-1-1';\nimport { AstFactory } from './AstFactory.js';\nimport type {\n Path,\n Pattern,\n PatternBind,\n QuerySelect,\n SparqlQuery,\n Term,\n TermLiteral,\n TermVariable,\n TripleCollection,\n TripleNesting,\n Wildcard,\n} from './sparql12Types.js';\n\nconst F = new AstFactory();\n\nfunction isLangDir(dir: string): dir is 'ltr' | 'rtl' {\n return dir === 'ltr' || dir === 'rtl';\n}\n\nexport function langTagHasCorrectRange(literal: TermLiteral): void {\n if (F.isTermLiteralLangStr(literal)) {\n const dirSplit = literal.langOrIri.split('--');\n if (dirSplit.length > 1) {\n const [ _, direction ] = dirSplit;\n if (!isLangDir(direction)) {\n throw new Error(`language direction \"${direction}\" of literal \"${JSON.stringify(literal)}\" is not is required range 'ltr' | 'rtl'.`);\n }\n }\n }\n}\n\nexport function findPatternBoundedVars(\n iter: SparqlQuery | Pattern | TripleNesting | TripleCollection | Path | Term | Wildcard,\n boundedVars: Set<string>,\n): void {\n if (F.isQuery(iter) || F.isUpdate(iter)) {\n if (F.isQuerySelect(iter) || F.isQueryDescribe(iter)) {\n if (iter.where && iter.variables.some(x => F.isWildcard(x))) {\n findPatternBoundedVars(iter.where, boundedVars);\n } else {\n for (const v of iter.variables) {\n findPatternBoundedVars(v, boundedVars);\n }\n }\n if (iter.solutionModifiers.group) {\n const grouping = iter.solutionModifiers.group;\n for (const g of grouping.groupings) {\n if ('variable' in g) {\n findPatternBoundedVars(g.variable, boundedVars);\n }\n }\n }\n if (iter.values?.values && iter.values.values.length > 0) {\n const values = iter.values.values;\n for (const v of Object.keys(values[0])) {\n boundedVars.add(v);\n }\n }\n }\n } else if (F.isTerm(iter)) {\n if (F.isTermVariable(iter)) {\n boundedVars.add(iter.value);\n }\n if (F.isTermTriple(iter)) {\n findPatternBoundedVars(iter.subject, boundedVars);\n findPatternBoundedVars(iter.predicate, boundedVars);\n findPatternBoundedVars(iter.object, boundedVars);\n }\n } else if (F.isTriple(iter)) {\n findPatternBoundedVars(iter.subject, boundedVars);\n findPatternBoundedVars(iter.predicate, boundedVars);\n findPatternBoundedVars(iter.object, boundedVars);\n for (const annotation of iter.annotations ?? []) {\n findPatternBoundedVars(\n F.isTripleCollection(annotation) ? annotation : annotation.val,\n boundedVars,\n );\n }\n } else if (F.isPath(iter)) {\n for (const item of iter.items) {\n findPatternBoundedVars(item, boundedVars);\n }\n } else if (F.isTripleCollection(iter) || F.isPatternBgp(iter)) {\n for (const triple of iter.triples) {\n findPatternBoundedVars(triple, boundedVars);\n }\n } else if (\n F.isPatternGroup(iter) || F.isPatternUnion(iter) || F.isPatternOptional(iter) || F.isPatternService(iter)) {\n for (const pattern of iter.patterns) {\n findPatternBoundedVars(pattern, boundedVars);\n }\n if (F.isPatternService(iter)) {\n findPatternBoundedVars(iter.name, boundedVars);\n }\n } else if (F.isPatternBind(iter)) {\n findPatternBoundedVars(iter.variable, boundedVars);\n } else if (F.isPatternValues(iter)) {\n for (const variable of Object.keys(iter.values.at(0) ?? {})) {\n boundedVars.add(variable);\n }\n } else if (F.isPatternGraph(iter)) {\n findPatternBoundedVars(iter.name, boundedVars);\n for (const pattern of iter.patterns) {\n findPatternBoundedVars(pattern, boundedVars);\n }\n }\n}\n\n/**\n * Verify that the projected variables (select head) are allowed:\n * - no group-by on select *\n * - if group-by, selected variables need to be collected by the group-by\n * - 'select ?var as ?other', ?other cannot be in scope\n */\nexport function queryProjectionIsGood(query: Pick<QuerySelect, 'variables' | 'solutionModifiers' | 'where'>): void {\n // NoGroupByOnWildcardSelect\n if (query.variables.length === 1 && F.isWildcard(query.variables[0])) {\n if (query.solutionModifiers.group !== undefined) {\n throw new Error('GROUP BY not allowed with wildcard');\n }\n return;\n }\n\n // CannotProjectUngroupedVars - can be skipped if `SELECT *`\n // Check for projection of ungrouped variable\n // Check can be skipped in case of wildcard select.\n const variables = <Exclude<typeof query.variables, [Wildcard]>> query.variables;\n const hasCountAggregate = variables.flatMap(\n varVal => F.isTerm(varVal) ? [] : getAggregatesOfExpression(<T11.Expression> varVal.expression),\n ).some(agg => agg.aggregation === 'count' && !agg.expression.some(arg => F.isWildcard(arg)));\n const groupBy = query.solutionModifiers.group;\n if (hasCountAggregate || groupBy) {\n // We have to check whether\n // 1. Variables used in projection are usable given the group by clause\n // 2. A selectCount will create an implicit group by clause.\n // Variables bound by preceding (expr AS ?var) expressions are in scope for later expressions.\n const asBoundVars = new Set<string>();\n for (const selectVar of variables) {\n if (F.isTerm(selectVar)) {\n if (!groupBy || !groupBy.groupings.map(groupvar =>\n getExpressionId(<T11.Expression | T11.SolutionModifierGroupBind> groupvar))\n .includes((getExpressionId(selectVar)))) {\n throw new Error('Variable not allowed in projection');\n }\n } else if (getAggregatesOfExpression(<T11.Expression> selectVar.expression).length === 0) {\n // Current value binding does not use aggregates\n const usedvars = new Set<string>();\n getVariablesFromExpression(<T11.Expression> selectVar.expression, usedvars);\n for (const usedvar of usedvars) {\n // If the var is created within the select, it is fine.\n if (asBoundVars.has(usedvar)) {\n continue;\n }\n if (!groupBy || !groupBy.groupings.map(groupVar =>\n getExpressionId(<T11.Expression | T11.SolutionModifierGroupBind>groupVar)).includes(usedvar)) {\n throw new Error(`Use of ungrouped variable in projection of operation (?${usedvar})`);\n }\n }\n }\n if (!F.isTerm(selectVar)) {\n // Register a var is created by a bind\n asBoundVars.add(selectVar.variable.value);\n }\n }\n }\n\n // NOTE 12: Check if id of each AS-selected column is not yet bound by subquery\n const subqueries = query.where.patterns.filter(pattern => pattern.type === 'query');\n if (subqueries.length > 0) {\n const selectBoundedVars = new Set<string>();\n for (const variable of variables) {\n if ('variable' in variable) {\n selectBoundedVars.add(variable.variable.value);\n }\n }\n\n // Look at in scope variables\n const vars = subqueries.flatMap<TermVariable | PatternBind | Wildcard>(sub => sub.variables)\n .map(v => F.isTerm(v) ? v.value : (F.isWildcard(v) ? '*' : v.variable.value));\n const subqueryIds = new Set(vars);\n for (const selectedVarId of selectBoundedVars) {\n if (subqueryIds.has(selectedVarId)) {\n throw new Error(`Target id of 'AS' (?${selectedVarId}) already used in subquery`);\n }\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@traqula/rules-sparql-1-2",
3
3
  "type": "module",
4
- "version": "1.1.1",
4
+ "version": "1.1.3",
5
5
  "description": "Traqula Lexer and Grammar Rules for sparql 1.2",
6
6
  "lsd:module": true,
7
7
  "license": "MIT",
@@ -41,8 +41,8 @@
41
41
  "build:cjs": "node \"../../node_modules/typescript/bin/tsc\" -b tsconfig.cjs.json"
42
42
  },
43
43
  "dependencies": {
44
- "@traqula/core": "^1.1.1",
45
- "@traqula/rules-sparql-1-1": "^1.1.1"
44
+ "@traqula/core": "^1.1.3",
45
+ "@traqula/rules-sparql-1-1": "^1.1.3"
46
46
  },
47
- "gitHead": "51799d80873e4f0fb0ca6ab778861f526d3a66d1"
47
+ "gitHead": "9f3269bc699a2990f2948c78883dabdac6908f26"
48
48
  }