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

Add internal function ql:isGeoPoint #1565

Merged
merged 5 commits into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion src/engine/QueryPlanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ ParsedQuery::GraphPattern QueryPlanner::uniteGraphPatterns(

// _____________________________________________________________________________
Variable QueryPlanner::generateUniqueVarName() {
return Variable{absl::StrCat(INTERNAL_VARIABLE_QUERY_PLANNER_PREFIX,
return Variable{absl::StrCat(QLEVER_INTERNAL_VARIABLE_QUERY_PLANNER_PREFIX,
_internalVarCount++)};
}

Expand Down
3 changes: 2 additions & 1 deletion src/engine/sparqlExpressions/CountStarExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ ExpressionResult CountStarExpression::evaluate(

auto varToColNoInternalVariables =
ctx->_variableToColumnMap | std::views::filter([](const auto& varAndIdx) {
return !varAndIdx.first.name().starts_with(INTERNAL_VARIABLE_PREFIX);
return !varAndIdx.first.name().starts_with(
QLEVER_INTERNAL_VARIABLE_PREFIX);
});
table.setNumColumns(std::ranges::distance(varToColNoInternalVariables));
table.resize(ctx->size());
Expand Down
18 changes: 13 additions & 5 deletions src/engine/sparqlExpressions/IsSomethingExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,19 @@ namespace detail {
// `...Expression` (`std::move` the arguments into the constructor). The
// function should be declared in `NaryExpression.h`.

// Expressions for `isIRI`, `isBlank`, `isLiteral`, and `isNumeric`. Note that
// the value getters already return the correct `Id`, hence `std::identity`.
// Expressions for the builtin functions `isIRI`, `isBlank`, `isLiteral`,
// `isNumeric`, and the custom function `isWktPoint`. Note that the value
// getters already return the correct `Id`, hence `std::identity`.
using isIriExpression = NARY<1, FV<std::identity, IsIriValueGetter>>;
using isBlankExpression = NARY<1, FV<std::identity, IsBlankNodeValueGetter>>;
using isLiteralExpression = NARY<1, FV<std::identity, IsLiteralValueGetter>>;
using isNumericExpression = NARY<1, FV<std::identity, IsNumericValueGetter>>;
// The expression for `bound` is slightly different because
// `IsValidValueGetter` returns a `bool` and not an `Id`.
using isBlankExpression =
NARY<1, FV<std::identity, IsValueIdValueGetter<Datatype::BlankNodeIndex>>>;
using isGeoPointExpression =
NARY<1, FV<std::identity, IsValueIdValueGetter<Datatype::GeoPoint>>>;

// The expression for `bound` is slightly different as `IsValidValueGetter`
// returns a `bool` and not an `Id`.
inline auto boolToId = [](bool b) { return Id::makeFromBool(b); };
using boundExpression = NARY<1, FV<decltype(boolToId), IsValidValueGetter>>;

Expand All @@ -49,6 +54,9 @@ SparqlExpression::Ptr makeIsLiteralExpression(SparqlExpression::Ptr arg) {
SparqlExpression::Ptr makeIsNumericExpression(SparqlExpression::Ptr arg) {
return std::make_unique<detail::isNumericExpression>(std::move(arg));
}
SparqlExpression::Ptr makeIsGeoPointExpression(SparqlExpression::Ptr arg) {
return std::make_unique<detail::isGeoPointExpression>(std::move(arg));
}
SparqlExpression::Ptr makeBoundExpression(SparqlExpression::Ptr arg) {
return std::make_unique<detail::boundExpression>(std::move(arg));
}
Expand Down
3 changes: 2 additions & 1 deletion src/engine/sparqlExpressions/NaryExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ std::optional<Variable> getVariableFromLangExpression(
SparqlExpression::Ptr makeEncodeForUriExpression(SparqlExpression::Ptr child);

SparqlExpression::Ptr makeIsIriExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeIsBlankExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeIsLiteralExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeIsNumericExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeIsBlankExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeIsGeoPointExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeBoundExpression(SparqlExpression::Ptr child);

// For a `function` that takes `std::vector<SparqlExpression::Ptr>` (size only
Expand Down
46 changes: 24 additions & 22 deletions src/engine/sparqlExpressions/SparqlExpressionValueGetters.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,19 +141,35 @@ struct StringValueGetter : Mixin<StringValueGetter> {
}
};

// Value getter for `isBlank`.
struct IsBlankNodeValueGetter : Mixin<IsBlankNodeValueGetter> {
using Mixin<IsBlankNodeValueGetter>::operator();
Id operator()(ValueId id, const EvaluationContext*) const {
return Id::makeFromBool(id.getDatatype() == Datatype::BlankNodeIndex);
// Boolean value getter that checks whether the given `Id` is a `ValueId` of the
// given `datatype`.
template <Datatype datatype>
struct IsValueIdValueGetter : Mixin<IsValueIdValueGetter<datatype>> {
using Mixin<IsValueIdValueGetter>::operator();
Id operator()(Id id, const EvaluationContext*) const {
return Id::makeFromBool(id.getDatatype() == datatype);
}

Id operator()(const LiteralOrIri&, const EvaluationContext*) const {
return Id::makeFromBool(false);
}
};

// Value getters for `isIRI`, `isBlank`, and `isLiteral`.
// Boolean value getter for `isNumeric`. Regarding which datatypes count as
// numeric, see https://www.w3.org/TR/sparql11-query/#operandDataTypes .
struct IsNumericValueGetter : Mixin<IsNumericValueGetter> {
using Mixin<IsNumericValueGetter>::operator();
Id operator()(ValueId id, const EvaluationContext*) const {
Datatype datatype = id.getDatatype();
return Id::makeFromBool(datatype == Datatype::Double ||
datatype == Datatype::Int);
}
Id operator()(const LiteralOrIri&, const EvaluationContext*) const {
return Id::makeFromBool(false);
}
};

// Boolean value getters for `isIRI`, `isBlank`, and `isLiteral`.
template <auto isSomethingFunction, auto isLiteralOrIriSomethingFunction>
struct IsSomethingValueGetter
: Mixin<IsSomethingValueGetter<isSomethingFunction,
Expand All @@ -176,22 +192,8 @@ using IsIriValueGetter =
using IsLiteralValueGetter =
IsSomethingValueGetter<&Index::Vocab::isLiteral, isLiteralPrefix>;

// Value getter for `isNumeric`. Regarding which datatypes count as numeric,
// see https://www.w3.org/TR/sparql11-query/#operandDataTypes .
struct IsNumericValueGetter : Mixin<IsNumericValueGetter> {
using Mixin<IsNumericValueGetter>::operator();
Id operator()(ValueId id, const EvaluationContext*) const {
Datatype datatype = id.getDatatype();
return Id::makeFromBool(datatype == Datatype::Double ||
datatype == Datatype::Int);
}
Id operator()(const LiteralOrIri&, const EvaluationContext*) const {
return Id::makeFromBool(false);
}
};

/// This class can be used as the `ValueGetter` argument of Expression
/// templates. It produces a `std::optional<DateYearOrDuration>`.
// This class can be used as the `ValueGetter` argument of Expression
// templates. It produces a `std::optional<DateYearOrDuration>`.
struct DateValueGetter : Mixin<DateValueGetter> {
using Mixin<DateValueGetter>::operator();
using Opt = std::optional<DateYearOrDuration>;
Expand Down
60 changes: 32 additions & 28 deletions src/global/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,66 +35,70 @@ constexpr inline size_t TEXT_PREDICATE_CARDINALITY_ESTIMATE = 1'000'000'000;

constexpr inline size_t GALLOP_THRESHOLD = 1000;

constexpr inline char INTERNAL_PREDICATE_PREFIX_NAME[] = "ql";

constexpr inline char INTERNAL_PREDICATE_PREFIX[] =
constexpr inline char QLEVER_INTERNAL_PREFIX_NAME[] = "ql";
constexpr inline char QLEVER_INTERNAL_PREFIX_URL[] =
"http://qlever.cs.uni-freiburg.de/builtin-functions/";

// Return a IRI of the form
// `<http://qlever.cs.uni-freiburg.de/builtin-functions/concatenationOfSuffixes>`
// Make a QLever-internal IRI from `QL_INTERNAL_PREFIX_URL` by appending the
// concatenation of the given `suffixes` and enclosing the result in angle
// brackets (const and non-const version).
template <
ad_utility::detail::constexpr_str_cat_impl::ConstexprString... suffixes>
constexpr std::string_view makeInternalIriConst() {
return ad_utility::constexprStrCat<"<", INTERNAL_PREDICATE_PREFIX,
constexpr std::string_view makeQleverInternalIriConst() {
return ad_utility::constexprStrCat<"<", QLEVER_INTERNAL_PREFIX_URL,
suffixes..., ">">();
}

inline std::string makeInternalIri(const auto&... suffixes) {
return absl::StrCat("<", std::string_view{INTERNAL_PREDICATE_PREFIX},
inline std::string makeQleverInternalIri(const auto&... suffixes) {
return absl::StrCat("<", std::string_view{QLEVER_INTERNAL_PREFIX_URL},
suffixes..., ">");
}
constexpr inline std::string_view INTERNAL_ENTITIES_URI_PREFIX =
ad_utility::constexprStrCat<"<", INTERNAL_PREDICATE_PREFIX>();
constexpr inline std::string_view INTERNAL_PREDICATE_PREFIX_IRI =
makeInternalIriConst<"">();

constexpr inline std::string_view QLEVER_INTERNAL_PREFIX_IRI =
makeQleverInternalIriConst<"">();
constexpr inline std::string_view
QLEVER_INTERNAL_PREFIX_IRI_WITHOUT_CLOSING_BRACKET =
ad_utility::constexprStrCat<"<", QLEVER_INTERNAL_PREFIX_URL>();
constexpr inline std::string_view CONTAINS_ENTITY_PREDICATE =
makeInternalIriConst<"contains-entity">();
makeQleverInternalIriConst<"contains-entity">();
constexpr inline std::string_view CONTAINS_WORD_PREDICATE =
makeInternalIriConst<"contains-word">();
makeQleverInternalIriConst<"contains-word">();

constexpr inline std::string_view INTERNAL_TEXT_MATCH_PREDICATE =
makeInternalIriConst<"text">();
constexpr inline std::string_view QLEVER_INTERNAL_TEXT_MATCH_PREDICATE =
makeQleverInternalIriConst<"text">();
constexpr inline std::string_view HAS_PREDICATE_PREDICATE =
makeInternalIriConst<"has-predicate">();
makeQleverInternalIriConst<"has-predicate">();
constexpr inline std::string_view HAS_PATTERN_PREDICATE =
makeInternalIriConst<"has-pattern">();
makeQleverInternalIriConst<"has-pattern">();
constexpr inline std::string_view DEFAULT_GRAPH_IRI =
makeInternalIriConst<"default-graph">();
constexpr inline std::string_view INTERNAL_GRAPH_IRI =
makeInternalIriConst<"internal-graph">();
makeQleverInternalIriConst<"default-graph">();
constexpr inline std::string_view QLEVER_INTERNAL_GRAPH_IRI =
makeQleverInternalIriConst<"internal-graph">();

constexpr inline std::pair<std::string_view, std::string_view> GEOF_PREFIX = {
"geof:", "http://www.opengis.net/def/function/geosparql/"};
constexpr inline std::pair<std::string_view, std::string_view> MATH_PREFIX = {
"math:", "http://www.w3.org/2005/xpath-functions/math#"};
constexpr inline std::pair<std::string_view, std::string_view> XSD_PREFIX = {
"xsd", "http://www.w3.org/2001/XMLSchema#"};
constexpr inline std::pair<std::string_view, std::string_view> QL_PREFIX = {
QLEVER_INTERNAL_PREFIX_NAME, QLEVER_INTERNAL_PREFIX_URL};

constexpr inline std::string_view INTERNAL_VARIABLE_PREFIX =
constexpr inline std::string_view QLEVER_INTERNAL_VARIABLE_PREFIX =
"?_QLever_internal_variable_";

constexpr inline std::string_view INTERNAL_BLANKNODE_VARIABLE_PREFIX =
constexpr inline std::string_view QLEVER_INTERNAL_BLANKNODE_VARIABLE_PREFIX =
"?_QLever_internal_variable_bn_";

constexpr inline std::string_view INTERNAL_VARIABLE_QUERY_PLANNER_PREFIX =
"?_QLever_internal_variable_qp_";
constexpr inline std::string_view
QLEVER_INTERNAL_VARIABLE_QUERY_PLANNER_PREFIX =
"?_QLever_internal_variable_qp_";

constexpr inline std::string_view SCORE_VARIABLE_PREFIX = "?ql_score_";
constexpr inline std::string_view MATCHINGWORD_VARIABLE_PREFIX =
"?ql_matchingword_";

constexpr inline std::string_view LANGUAGE_PREDICATE =
makeInternalIriConst<"langtag">();
makeQleverInternalIriConst<"langtag">();

// this predicate is one of the supported identifiers for the SpatialJoin class.
// It joins the two objects, if their distance is smaller or equal to the
Expand Down
2 changes: 1 addition & 1 deletion src/global/SpecialIds.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ inline const ad_utility::HashMap<std::string, Id>& specialIds() {
{S{HAS_PREDICATE_PREDICATE}, Id::fromBits(1)},
{S{HAS_PATTERN_PREDICATE}, Id::fromBits(2)},
{S{DEFAULT_GRAPH_IRI}, Id::fromBits(3)},
{S{INTERNAL_GRAPH_IRI}, Id::fromBits(4)}};
{S{QLEVER_INTERNAL_GRAPH_IRI}, Id::fromBits(4)}};

// Perform the following checks: All the special IDs are unique, all of them
// have the `Undefined` datatype, but none of them is equal to the "actual"
Expand Down
2 changes: 1 addition & 1 deletion src/index/ConstantsIndexBuilding.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ constexpr inline std::string_view TMP_BASENAME_COMPRESSION =
".tmp.for-prefix-compression";

// _________________________________________________________________
constexpr inline std::string_view INTERNAL_INDEX_INFIX = ".internal";
constexpr inline std::string_view QLEVER_INTERNAL_INDEX_INFIX = ".internal";

// _________________________________________________________________
// The degree of parallelism that is used for the index building step, where the
Expand Down
8 changes: 4 additions & 4 deletions src/index/IndexImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ std::pair<size_t, size_t> IndexImpl::createInternalPSOandPOS(
auto&& internalTriplesPsoSorter) {
auto onDiskBaseBackup = onDiskBase_;
auto configurationJsonBackup = configurationJson_;
onDiskBase_.append(INTERNAL_INDEX_INFIX);
onDiskBase_.append(QLEVER_INTERNAL_INDEX_INFIX);
auto internalTriplesUnique = ad_utility::uniqueBlockView(
internalTriplesPsoSorter.template getSortedBlocks<0>());
createPSOAndPOSImpl(NumColumnsIndexBuilding, std::move(internalTriplesUnique),
Expand Down Expand Up @@ -560,7 +560,7 @@ IndexBuilderDataAsStxxlVector IndexImpl::passFileForVocabulary(
idOfHasPatternDuringIndexBuilding_ =
mergeRes.specialIdMapping().at(HAS_PATTERN_PREDICATE);
idOfInternalGraphDuringIndexBuilding_ =
mergeRes.specialIdMapping().at(INTERNAL_GRAPH_IRI);
mergeRes.specialIdMapping().at(QLEVER_INTERNAL_GRAPH_IRI);
LOG(INFO) << "Number of words in external vocabulary: "
<< res.vocabularyMetaData_.numWordsTotal() - sizeInternalVocabulary
<< std::endl;
Expand Down Expand Up @@ -858,7 +858,7 @@ void IndexImpl::createFromOnDiskIndex(const string& onDiskBase) {
<< vocab_.size() << std::endl;

auto range1 =
vocab_.prefixRanges(absl::StrCat("<", INTERNAL_PREDICATE_PREFIX));
vocab_.prefixRanges(QLEVER_INTERNAL_PREFIX_IRI_WITHOUT_CLOSING_BRACKET);
auto range2 = vocab_.prefixRanges("@");
auto isInternalId = [range1, range2](Id id) {
// TODO<joka921> What about internal vocab stuff for update queries? this
Expand Down Expand Up @@ -1464,7 +1464,7 @@ size_t IndexImpl::getCardinality(const TripleComponent& comp,
// or objects anyway.
// TODO<joka921> Find out what the effect of this special case is for the
// query planning.
if (comp == INTERNAL_TEXT_MATCH_PREDICATE) {
if (comp == QLEVER_INTERNAL_TEXT_MATCH_PREDICATE) {
return TEXT_PREDICATE_CARDINALITY_ESTIMATE;
}
if (std::optional<Id> relId = comp.toValueId(getVocab()); relId.has_value()) {
Expand Down
3 changes: 2 additions & 1 deletion src/index/Permutation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ void Permutation::loadFromDisk(const std::string& onDiskBase,
internalPermutation_ =
std::make_unique<Permutation>(permutation_, allocator_);
internalPermutation_->loadFromDisk(
absl::StrCat(onDiskBase, INTERNAL_INDEX_INFIX), isInternalId_, false);
absl::StrCat(onDiskBase, QLEVER_INTERNAL_INDEX_INFIX), isInternalId_,
false);
}
if constexpr (MetaData::isMmapBased_) {
meta_.setup(onDiskBase + ".index" + fileSuffix_ + MMAP_FILE_SUFFIX,
Expand Down
2 changes: 1 addition & 1 deletion src/index/Vocabulary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ bool Vocabulary<S, C, I>::shouldEntityBeExternalized(
// Never externalize the internal IRIs as they are sometimes added before or
// after the externalization happens and we thus get inconsistent behavior
// etc. for `ql:langtag`.
if (word.starts_with(INTERNAL_ENTITIES_URI_PREFIX)) {
if (word.starts_with(QLEVER_INTERNAL_PREFIX_IRI_WITHOUT_CLOSING_BRACKET)) {
return false;
}
// Never externalize the special IRIs starting with `@` (for example,
Expand Down
3 changes: 2 additions & 1 deletion src/index/VocabularyMerger.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ struct VocabularyMetaData {
size_t numBlankNodesTotal_ = 0;
IdRangeForPrefix langTaggedPredicates_{
std::string{ad_utility::languageTaggedPredicatePrefix}};
IdRangeForPrefix internalEntities_{std::string{INTERNAL_ENTITIES_URI_PREFIX}};
IdRangeForPrefix internalEntities_{
std::string{QLEVER_INTERNAL_PREFIX_IRI_WITHOUT_CLOSING_BRACKET}};

ad_utility::HashMap<std::string, Id> specialIdMapping_;
const ad_utility::HashMap<std::string, Id>* globalSpecialIds_ =
Expand Down
13 changes: 7 additions & 6 deletions src/parser/ParsedQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ void ParsedQuery::registerVariablesVisibleInQueryBody(
// _____________________________________________________________________________
void ParsedQuery::registerVariableVisibleInQueryBody(const Variable& variable) {
auto addVariable = [&variable](auto& clause) {
if (!variable.name().starts_with(INTERNAL_VARIABLE_PREFIX)) {
if (!variable.name().starts_with(QLEVER_INTERNAL_VARIABLE_PREFIX)) {
clause.addVisibleVariable(variable);
}
};
Expand Down Expand Up @@ -285,7 +285,8 @@ void ParsedQuery::GraphPattern::addLanguageFilter(const Variable& variable,
if (triple.o_ == variable &&
(triple.p_._operation == PropertyPath::Operation::IRI &&
!isVariable(triple.p_)) &&
!triple.p_._iri.starts_with(INTERNAL_ENTITIES_URI_PREFIX)) {
!triple.p_._iri.starts_with(
QLEVER_INTERNAL_PREFIX_IRI_WITHOUT_CLOSING_BRACKET)) {
matchingTriples.push_back(&triple);
}
}
Expand Down Expand Up @@ -492,14 +493,14 @@ void ParsedQuery::addOrderByClause(OrderClause orderClause, bool isGroupBy,

// ________________________________________________________________
Variable ParsedQuery::getNewInternalVariable() {
auto variable =
Variable{absl::StrCat(INTERNAL_VARIABLE_PREFIX, numInternalVariables_)};
auto variable = Variable{
absl::StrCat(QLEVER_INTERNAL_VARIABLE_PREFIX, numInternalVariables_)};
numInternalVariables_++;
return variable;
}

Variable ParsedQuery::blankNodeToInternalVariable(std::string_view blankNode) {
AD_CONTRACT_CHECK(blankNode.starts_with("_:"));
return Variable{
absl::StrCat(INTERNAL_BLANKNODE_VARIABLE_PREFIX, blankNode.substr(2))};
return Variable{absl::StrCat(QLEVER_INTERNAL_BLANKNODE_VARIABLE_PREFIX,
blankNode.substr(2))};
}
2 changes: 1 addition & 1 deletion src/parser/SparqlParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ParsedQuery SparqlParser::parseQuery(std::string query) {
using S = std::string;
sparqlParserHelpers::ParserAndVisitor p{
std::move(query),
{{S{INTERNAL_PREDICATE_PREFIX_NAME}, S{INTERNAL_PREDICATE_PREFIX_IRI}}}};
{{S{QLEVER_INTERNAL_PREFIX_NAME}, S{QLEVER_INTERNAL_PREFIX_IRI}}}};
// Note: `AntlrParser::query` is a method of `AntlrParser` (which is an alias
// for `SparqlAutomaticParser`) that returns the `QueryContext*` for the whole
// query.
Expand Down
Loading
Loading