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

GH-2864: Fix algebra function name for the hash functions. #2865

Merged
merged 3 commits into from
Dec 4, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Query write-read
afs committed Nov 27, 2024
commit 1a65ba2d21f824894ca0fa5969ef6a0005c9ec85
Original file line number Diff line number Diff line change
@@ -25,7 +25,6 @@
import org.apache.jena.atlas.lib.Bytes;
import org.apache.jena.atlas.lib.Cache;
import org.apache.jena.atlas.lib.CacheFactory;
import org.apache.jena.atlas.lib.Lib;
import org.apache.jena.datatypes.xsd.XSDDatatype;
import org.apache.jena.graph.Node;
import org.apache.jena.sparql.ARQInternalErrorException;
@@ -102,6 +101,6 @@ private NodeValue calculate(NodeValue v) {

@Override
public String getFunctionPrintName(SerializationContext cxt) {
return Lib.uppercase(super.getFunctionPrintName(cxt));
return printName;
}
}
139 changes: 139 additions & 0 deletions jena-arq/src/main/java/org/apache/jena/sparql/util/QueryCheck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.jena.sparql.util;

import org.apache.jena.atlas.io.IndentedLineBuffer;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryException;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.sparql.algebra.Algebra;
import org.apache.jena.sparql.algebra.Op;
import org.apache.jena.sparql.core.QueryCheckException;
import org.apache.jena.sparql.lang.SPARQLParserRegistry;
import org.apache.jena.sparql.sse.SSE;
import org.apache.jena.sparql.sse.SSE_ParseException;
import org.apache.jena.sparql.sse.WriterSSE;
import org.apache.jena.sparql.sse.builders.SSE_BuildException;

/**
* Checking read-write operations on query objects.
*/
public class QueryCheck {

/**
* Parse a query string,
* then check the query can be written and read back in again,
* then check the algebra form can be written and read back in again.
* Throw an exception if there are any problems.
*
* @see #checkParse
* @see #checkOp(Query, boolean)
*/
public static void checkQuery(String queryString) {
Query query = QueryFactory.create(queryString);
checkParse(query);
checkOp(query, true);
}

/**
* Write a query to a string,
* parse that string to get a second query object,
* and check the two query objects are
* the same (blank node isomorphic).
*/
public static void checkParse(Query query) {
if ( !SPARQLParserRegistry.get().containsFactory(query.getSyntax()) )
return;

IndentedLineBuffer buff = new IndentedLineBuffer();
query.serialize(buff, query.getSyntax());

String tmp = buff.toString();

Query query2 = null;
try {
String baseURI = null;
if ( !query.explicitlySetBaseURI() )
// Not in query - use the same one (e.g. file read from) .
baseURI = query.getBaseURI();

query2 = QueryFactory.create(tmp, baseURI, query.getSyntax());

if ( query2 == null )
return;
} catch (UnsupportedOperationException ex) {
// No parser after all.
return;
} catch (QueryException ex) {
System.err.println(tmp);
throw new QueryCheckException("could not parse output query", ex);
}

if ( query.hashCode() != query2.hashCode() )
throw new QueryCheckException("Reparsed query hashCode does not equal parsed input query \n"+
"Query (hashCode: " + query.hashCode()+ ")=\n" + query + "\n\n"+
"Query2 (hashCode: " + query2.hashCode() + ")=\n" + query2);

if ( !query.equals(query2) ) {
if ( false ) {
System.err.println(query);
System.err.println(query2);
}
throw new QueryCheckException("reparsed output does not equal parsed input");
}
}

/**
* Convert a query to the SPARQL algebra with optionally algebra optimizations,
* write the algebra to a string,
* parse that string to get second algebra object
* and check the two algebra objects are the same (blank node isomorphic).
*/
public static void checkOp(Query query, boolean optimizeAlgebra) {
IndentedLineBuffer buff = new IndentedLineBuffer();
Op op = Algebra.compile(query);
if ( optimizeAlgebra )
op = Algebra.optimize(op);
WriterSSE.out(buff, op, query);
String str = buff.toString();

try {
Op op2 = SSE.parseOp(str);
if ( op.hashCode() != op2.hashCode() ) {
op.hashCode();
op2.hashCode();
dump(op, op2);
throw new QueryCheckException("reparsed algebra expression hashCode does not equal algebra from query");
}
if ( !op.equals(op2) ) {
dump(op, op2);
throw new QueryCheckException("reparsed algebra expression does not equal query algebra");
}
} catch (SSE_ParseException | SSE_BuildException ex) {
throw ex;
}
}

private static void dump(Op op, Op op2) {
System.err.println("***********");
System.err.println(op);
System.err.println(op2);
System.err.println("***********");
}
}
122 changes: 0 additions & 122 deletions jena-arq/src/main/java/org/apache/jena/sparql/util/QueryUtils.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@
import org.apache.jena.query.Query ;
import org.apache.jena.query.Syntax ;
import org.apache.jena.sparql.sse.SSE_ParseException ;
import org.apache.jena.sparql.util.QueryUtils ;
import org.apache.jena.sparql.util.QueryCheck ;

public class SerializationTest implements Runnable
{
@@ -62,7 +62,7 @@ protected void runTestWorker(Query query, Syntax syntax)
// Query syntax and algebra tests.

try {
QueryUtils.checkParse(query) ;
QueryCheck.checkParse(query) ;
}
catch (RuntimeException ex)
{
@@ -73,7 +73,7 @@ protected void runTestWorker(Query query, Syntax syntax)
}

try {
QueryUtils.checkOp(query, true) ;
QueryCheck.checkOp(query, true) ;
} catch (SSE_ParseException ex)
{
System.err.println("**** Test: "+testEntry.getName()) ;
Original file line number Diff line number Diff line change
@@ -29,7 +29,8 @@
TestFmtUtils.class,
TestContextUtils.class,
TestIsoMatcher.class,
TestGraphUtils.class
TestGraphUtils.class,
TestQueryCheckRW.class
})
public class TS_Util
{ }
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.jena.sparql.util;

import org.junit.jupiter.api.Test;

import org.apache.jena.query.Query;
import org.apache.jena.query.QueryFactory;

/**
* Test query string parsing, conversion to the algebra
*/
public class TestQueryCheckRW {

@Test public void rtt_abs() {
// ABS is printed 'abs'
test("SELECT * { BIND(ABS(?X) as ?absX) }");
}

@Test public void rtt_hashFunction_md5() {
// MD5 is printed 'MD5' and is 'md5' in algebra.
test("SELECT * { FILTER ( MD5('abc') != 0 ) }");
}

@Test public void rtt_hashFunction_sha1() {
test("SELECT * { FILTER ( SHA1('abc') != 0 ) }");
}

@Test public void rtt_hashFunction_sha256() {
test("SELECT * { FILTER ( SHA256('abc') != 0 ) }");
}

@Test public void rtt_hashFunction_sha384() {
test("SELECT * { FILTER ( SHA384('abc') != 0 ) }");
}

@Test public void rtt_hashFunction_sha512() {
test("SELECT * { FILTER ( SHA512('abc') != 0 ) }");
}

private static void test(String queryString) {
Query query = QueryFactory.create(queryString);
QueryCheck.checkParse(query);
QueryCheck.checkOp(query, false);
QueryCheck.checkOp(query, true);
}
}
Loading