#include "function/aggregate/count_star.h"
#include "function/arithmetic/vector_arithmetic_functions.h"
#include "function/cast/functions/cast_from_string_functions.h"
#include "function/list/vector_list_functions.h"
#include "function/string/vector_string_functions.h"
#include "function/struct/vector_struct_functions.h"
#include "parser/expression/parsed_case_expression.h"
#include "parser/expression/parsed_function_expression.h"
#include "parser/expression/parsed_lambda_expression.h"
#include "parser/expression/parsed_literal_expression.h"
#include "parser/expression/parsed_parameter_expression.h"
#include "parser/expression/parsed_property_expression.h"
#include "parser/expression/parsed_subquery_expression.h"
#include "parser/expression/parsed_variable_expression.h"
#include "parser/transformer.h"
using namespace lbug::common;
using namespace lbug::function;
namespace lbug {
namespace parser {
std::unique_ptr<ParsedExpression> Transformer::transformExpression(
CypherParser::OC_ExpressionContext& ctx) {
return transformOrExpression(*ctx.oC_OrExpression());
}
std::unique_ptr<ParsedExpression> Transformer::transformOrExpression(
CypherParser::OC_OrExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto& xorExpression : ctx.oC_XorExpression()) {
auto next = transformXorExpression(*xorExpression);
if (!expression) {
expression = std::move(next);
} else {
auto rawName = expression->getRawName() + " OR " + next->getRawName();
expression = std::make_unique<ParsedExpression>(ExpressionType::OR,
std::move(expression), std::move(next), rawName);
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformXorExpression(
CypherParser::OC_XorExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto& andExpression : ctx.oC_AndExpression()) {
auto next = transformAndExpression(*andExpression);
if (!expression) {
expression = std::move(next);
} else {
auto rawName = expression->getRawName() + " XOR " + next->getRawName();
expression = std::make_unique<ParsedExpression>(ExpressionType::XOR,
std::move(expression), std::move(next), rawName);
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformAndExpression(
CypherParser::OC_AndExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto& notExpression : ctx.oC_NotExpression()) {
auto next = transformNotExpression(*notExpression);
if (!expression) {
expression = std::move(next);
} else {
auto rawName = expression->getRawName() + " AND " + next->getRawName();
expression = std::make_unique<ParsedExpression>(ExpressionType::AND,
std::move(expression), std::move(next), rawName);
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformNotExpression(
CypherParser::OC_NotExpressionContext& ctx) {
auto result = transformComparisonExpression(*ctx.oC_ComparisonExpression());
if (!ctx.NOT().empty()) {
for ([[maybe_unused]] auto& _ : ctx.NOT()) {
auto rawName = "NOT " + result->toString();
result = std::make_unique<ParsedExpression>(ExpressionType::NOT, std::move(result),
std::move(rawName));
}
}
return result;
}
std::unique_ptr<ParsedExpression> Transformer::transformComparisonExpression(
CypherParser::OC_ComparisonExpressionContext& ctx) {
if (1 == ctx.iC_BitwiseOrOperatorExpression().size()) {
return transformBitwiseOrOperatorExpression(*ctx.iC_BitwiseOrOperatorExpression(0));
}
DASSERT(ctx.iC_ComparisonOperator().size() == 1);
auto left = transformBitwiseOrOperatorExpression(*ctx.iC_BitwiseOrOperatorExpression(0));
auto right = transformBitwiseOrOperatorExpression(*ctx.iC_BitwiseOrOperatorExpression(1));
auto comparisonOperator = ctx.iC_ComparisonOperator()[0]->getText();
if (comparisonOperator == "=") {
return std::make_unique<ParsedExpression>(ExpressionType::EQUALS, std::move(left),
std::move(right), ctx.getText());
} else if (comparisonOperator == "<>") {
return std::make_unique<ParsedExpression>(ExpressionType::NOT_EQUALS, std::move(left),
std::move(right), ctx.getText());
} else if (comparisonOperator == ">") {
return std::make_unique<ParsedExpression>(ExpressionType::GREATER_THAN, std::move(left),
std::move(right), ctx.getText());
} else if (comparisonOperator == ">=") {
return std::make_unique<ParsedExpression>(ExpressionType::GREATER_THAN_EQUALS,
std::move(left), std::move(right), ctx.getText());
} else if (comparisonOperator == "<") {
return std::make_unique<ParsedExpression>(ExpressionType::LESS_THAN, std::move(left),
std::move(right), ctx.getText());
} else {
DASSERT(comparisonOperator == "<=");
return std::make_unique<ParsedExpression>(ExpressionType::LESS_THAN_EQUALS, std::move(left),
std::move(right), ctx.getText());
}
}
std::unique_ptr<ParsedExpression> Transformer::transformBitwiseOrOperatorExpression(
CypherParser::IC_BitwiseOrOperatorExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto i = 0ul; i < ctx.iC_BitwiseAndOperatorExpression().size(); ++i) {
auto next = transformBitwiseAndOperatorExpression(*ctx.iC_BitwiseAndOperatorExpression(i));
if (!expression) {
expression = std::move(next);
} else {
auto rawName = expression->getRawName() + " | " + next->getRawName();
expression = std::make_unique<ParsedFunctionExpression>(BitwiseOrFunction::name,
std::move(expression), std::move(next), rawName);
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformBitwiseAndOperatorExpression(
CypherParser::IC_BitwiseAndOperatorExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto i = 0ul; i < ctx.iC_BitShiftOperatorExpression().size(); ++i) {
auto next = transformBitShiftOperatorExpression(*ctx.iC_BitShiftOperatorExpression(i));
if (!expression) {
expression = std::move(next);
} else {
auto rawName = expression->getRawName() + " & " + next->getRawName();
expression = std::make_unique<ParsedFunctionExpression>(BitwiseAndFunction::name,
std::move(expression), std::move(next), rawName);
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformBitShiftOperatorExpression(
CypherParser::IC_BitShiftOperatorExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto i = 0ul; i < ctx.oC_AddOrSubtractExpression().size(); ++i) {
auto next = transformAddOrSubtractExpression(*ctx.oC_AddOrSubtractExpression(i));
if (!expression) {
expression = std::move(next);
} else {
auto bitShiftOperator = ctx.iC_BitShiftOperator(i - 1)->getText();
auto rawName =
expression->getRawName() + " " + bitShiftOperator + " " + next->getRawName();
if (bitShiftOperator == "<<") {
expression = std::make_unique<ParsedFunctionExpression>(BitShiftLeftFunction::name,
std::move(expression), std::move(next), rawName);
} else {
DASSERT(bitShiftOperator == ">>");
expression = std::make_unique<ParsedFunctionExpression>(BitShiftRightFunction::name,
std::move(expression), std::move(next), rawName);
}
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformAddOrSubtractExpression(
CypherParser::OC_AddOrSubtractExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto i = 0ul; i < ctx.oC_MultiplyDivideModuloExpression().size(); ++i) {
auto next =
transformMultiplyDivideModuloExpression(*ctx.oC_MultiplyDivideModuloExpression(i));
if (!expression) {
expression = std::move(next);
} else {
auto arithmeticOperator = ctx.iC_AddOrSubtractOperator(i - 1)->getText();
auto rawName =
expression->getRawName() + " " + arithmeticOperator + " " + next->getRawName();
expression = std::make_unique<ParsedFunctionExpression>(arithmeticOperator,
std::move(expression), std::move(next), rawName);
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformMultiplyDivideModuloExpression(
CypherParser::OC_MultiplyDivideModuloExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto i = 0ul; i < ctx.oC_PowerOfExpression().size(); i++) {
auto next = transformPowerOfExpression(*ctx.oC_PowerOfExpression(i));
if (!expression) {
expression = std::move(next);
} else {
auto arithmeticOperator = ctx.iC_MultiplyDivideModuloOperator(i - 1)->getText();
auto rawName =
expression->getRawName() + " " + arithmeticOperator + " " + next->getRawName();
expression = std::make_unique<ParsedFunctionExpression>(arithmeticOperator,
std::move(expression), std::move(next), rawName);
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformPowerOfExpression(
CypherParser::OC_PowerOfExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> expression;
for (auto& stringListNullOperatorExpression : ctx.oC_StringListNullOperatorExpression()) {
auto next = transformStringListNullOperatorExpression(*stringListNullOperatorExpression);
if (!expression) {
expression = std::move(next);
} else {
auto rawName = expression->getRawName() + " ^ " + next->getRawName();
expression = std::make_unique<ParsedFunctionExpression>(PowerFunction::name,
std::move(expression), std::move(next), rawName);
}
}
return expression;
}
std::unique_ptr<ParsedExpression> Transformer::transformUnaryAddSubtractOrFactorialExpression(
CypherParser::OC_UnaryAddSubtractOrFactorialExpressionContext& ctx) {
auto atomCtx = ctx.oC_PropertyOrLabelsExpression()->oC_Atom();
bool isNumberLiteral = atomCtx->oC_Literal() && atomCtx->oC_Literal()->oC_NumberLiteral();
std::unique_ptr<ParsedExpression> result;
if (isNumberLiteral) {
result = transformNumberLiteral(*atomCtx->oC_Literal()->oC_NumberLiteral(),
ctx.MINUS().size() % 2 == 1);
} else {
result = transformPropertyOrLabelsExpression(*ctx.oC_PropertyOrLabelsExpression());
}
if (ctx.FACTORIAL()) { auto raw = result->toString() + "!";
result = std::make_unique<ParsedFunctionExpression>(FactorialFunction::name,
std::move(result), std::move(raw));
}
if (!ctx.MINUS().empty() && !isNumberLiteral) {
for ([[maybe_unused]] auto& _ : ctx.MINUS()) {
auto raw = "-" + result->toString();
result = std::make_unique<ParsedFunctionExpression>(NegateFunction::name,
std::move(result), std::move(raw));
}
}
return result;
}
std::unique_ptr<ParsedExpression> Transformer::transformStringListNullOperatorExpression(
CypherParser::OC_StringListNullOperatorExpressionContext& ctx) {
auto unaryAddSubtractOrFactorialExpression = transformUnaryAddSubtractOrFactorialExpression(
*ctx.oC_UnaryAddSubtractOrFactorialExpression());
if (ctx.oC_NullOperatorExpression()) {
return transformNullOperatorExpression(*ctx.oC_NullOperatorExpression(),
std::move(unaryAddSubtractOrFactorialExpression));
}
if (!ctx.oC_ListOperatorExpression().empty()) {
auto result = transformListOperatorExpression(*ctx.oC_ListOperatorExpression(0),
std::move(unaryAddSubtractOrFactorialExpression));
for (auto i = 1u; i < ctx.oC_ListOperatorExpression().size(); ++i) {
result = transformListOperatorExpression(*ctx.oC_ListOperatorExpression(i),
std::move(result));
}
return result;
}
if (ctx.oC_StringOperatorExpression()) {
return transformStringOperatorExpression(*ctx.oC_StringOperatorExpression(),
std::move(unaryAddSubtractOrFactorialExpression));
}
return unaryAddSubtractOrFactorialExpression;
}
std::unique_ptr<ParsedExpression> Transformer::transformStringOperatorExpression(
CypherParser::OC_StringOperatorExpressionContext& ctx,
std::unique_ptr<ParsedExpression> propertyExpression) {
auto rawExpression = propertyExpression->getRawName() + " " + ctx.getText();
auto right = transformPropertyOrLabelsExpression(*ctx.oC_PropertyOrLabelsExpression());
if (ctx.STARTS()) {
return std::make_unique<ParsedFunctionExpression>(StartsWithFunction::name,
std::move(propertyExpression), std::move(right), rawExpression);
} else if (ctx.ENDS()) {
return std::make_unique<ParsedFunctionExpression>(EndsWithFunction::name,
std::move(propertyExpression), std::move(right), rawExpression);
} else if (ctx.CONTAINS()) {
return std::make_unique<ParsedFunctionExpression>(ContainsFunction::name,
std::move(propertyExpression), std::move(right), rawExpression);
} else {
DASSERT(ctx.oC_RegularExpression());
return std::make_unique<ParsedFunctionExpression>(RegexpFullMatchFunction::name,
std::move(propertyExpression), std::move(right), rawExpression);
}
}
std::unique_ptr<ParsedExpression> Transformer::transformListOperatorExpression(
CypherParser::OC_ListOperatorExpressionContext& ctx, std::unique_ptr<ParsedExpression> child) {
auto raw = child->getRawName() + ctx.getText();
if (ctx.IN()) { auto listContains =
std::make_unique<ParsedFunctionExpression>(ListContainsFunction::name, std::move(raw));
auto right = transformPropertyOrLabelsExpression(*ctx.oC_PropertyOrLabelsExpression());
listContains->addChild(std::move(right));
listContains->addChild(std::move(child));
return listContains;
}
if (ctx.COLON() || ctx.DOTDOT()) { auto listSlice =
std::make_unique<ParsedFunctionExpression>(ListSliceFunction::name, std::move(raw));
listSlice->addChild(std::move(child));
std::unique_ptr<ParsedExpression> left;
std::unique_ptr<ParsedExpression> right;
if (ctx.oC_Expression().size() == 2) { left = transformExpression(*ctx.oC_Expression(0));
right = transformExpression(*ctx.oC_Expression(1));
} else if (ctx.oC_Expression().size() == 0) { left = std::make_unique<ParsedLiteralExpression>(Value(1), "1");
right = std::make_unique<ParsedLiteralExpression>(Value(-1), "-1");
} else {
if (ctx.children[1]->getText() == ":" ||
ctx.children[1]->getText() == "..") { left = std::make_unique<ParsedLiteralExpression>(Value(1), "1");
right = transformExpression(*ctx.oC_Expression(0));
} else { left = transformExpression(*ctx.oC_Expression(0));
right = std::make_unique<ParsedLiteralExpression>(Value(-1), "-1");
}
}
listSlice->addChild(std::move(left));
listSlice->addChild(std::move(right));
return listSlice;
}
auto listExtract =
std::make_unique<ParsedFunctionExpression>(ListExtractFunction::name, std::move(raw));
listExtract->addChild(std::move(child));
DASSERT(ctx.oC_Expression().size() == 1);
listExtract->addChild(transformExpression(*ctx.oC_Expression()[0]));
return listExtract;
}
std::unique_ptr<ParsedExpression> Transformer::transformNullOperatorExpression(
CypherParser::OC_NullOperatorExpressionContext& ctx,
std::unique_ptr<ParsedExpression> propertyExpression) {
auto rawExpression = propertyExpression->getRawName() + " " + ctx.getText();
DASSERT(ctx.IS() && ctx.NULL_());
return ctx.NOT() ? std::make_unique<ParsedExpression>(ExpressionType::IS_NOT_NULL,
std::move(propertyExpression), rawExpression) :
std::make_unique<ParsedExpression>(ExpressionType::IS_NULL,
std::move(propertyExpression), rawExpression);
}
std::unique_ptr<ParsedExpression> Transformer::transformPropertyOrLabelsExpression(
CypherParser::OC_PropertyOrLabelsExpressionContext& ctx) {
auto atom = transformAtom(*ctx.oC_Atom());
if (!ctx.oC_PropertyLookup().empty()) {
auto lookUpCtx = ctx.oC_PropertyLookup(0);
auto result = createPropertyExpression(*lookUpCtx, std::move(atom));
for (auto i = 1u; i < ctx.oC_PropertyLookup().size(); ++i) {
lookUpCtx = ctx.oC_PropertyLookup(i);
result = createPropertyExpression(*lookUpCtx, std::move(result));
}
return result;
}
return atom;
}
std::unique_ptr<ParsedExpression> Transformer::transformAtom(CypherParser::OC_AtomContext& ctx) {
if (ctx.oC_Literal()) {
return transformLiteral(*ctx.oC_Literal());
} else if (ctx.oC_Parameter()) {
return transformParameterExpression(*ctx.oC_Parameter());
} else if (ctx.oC_CaseExpression()) {
return transformCaseExpression(*ctx.oC_CaseExpression());
} else if (ctx.oC_ParenthesizedExpression()) {
return transformParenthesizedExpression(*ctx.oC_ParenthesizedExpression());
} else if (ctx.oC_FunctionInvocation()) {
return transformFunctionInvocation(*ctx.oC_FunctionInvocation());
} else if (ctx.oC_PathPatterns()) {
return transformPathPattern(*ctx.oC_PathPatterns());
} else if (ctx.oC_ExistCountSubquery()) {
return transformExistCountSubquery(*ctx.oC_ExistCountSubquery());
} else if (ctx.oC_Quantifier()) {
return transformOcQuantifier(*ctx.oC_Quantifier());
} else {
DASSERT(ctx.oC_Variable());
return std::make_unique<ParsedVariableExpression>(transformVariable(*ctx.oC_Variable()),
ctx.getText());
}
}
std::unique_ptr<ParsedExpression> Transformer::transformLiteral(
CypherParser::OC_LiteralContext& ctx) {
if (ctx.oC_NumberLiteral()) {
return transformNumberLiteral(*ctx.oC_NumberLiteral(), false );
} else if (ctx.oC_BooleanLiteral()) {
return transformBooleanLiteral(*ctx.oC_BooleanLiteral());
} else if (ctx.StringLiteral()) {
return std::make_unique<ParsedLiteralExpression>(
Value(LogicalType::STRING(), transformStringLiteral(*ctx.StringLiteral())),
ctx.getText());
} else if (ctx.NULL_()) {
return std::make_unique<ParsedLiteralExpression>(Value::createNullValue(), ctx.getText());
} else if (ctx.iC_StructLiteral()) {
return transformStructLiteral(*ctx.iC_StructLiteral());
} else {
DASSERT(ctx.oC_ListLiteral());
return transformListLiteral(*ctx.oC_ListLiteral());
}
}
std::unique_ptr<ParsedExpression> Transformer::transformBooleanLiteral(
CypherParser::OC_BooleanLiteralContext& ctx) {
if (ctx.TRUE()) {
return std::make_unique<ParsedLiteralExpression>(Value(true), ctx.getText());
} else if (ctx.FALSE()) {
return std::make_unique<ParsedLiteralExpression>(Value(false), ctx.getText());
}
UNREACHABLE_CODE;
}
std::unique_ptr<ParsedExpression> Transformer::transformListLiteral(
CypherParser::OC_ListLiteralContext& ctx) {
auto listCreation =
std::make_unique<ParsedFunctionExpression>(ListCreationFunction::name, ctx.getText());
if (ctx.oC_Expression() == nullptr) { return listCreation;
}
listCreation->addChild(transformExpression(*ctx.oC_Expression()));
for (auto& listEntry : ctx.iC_ListEntry()) {
if (listEntry->oC_Expression() == nullptr) {
auto nullValue = Value::createNullValue();
listCreation->addChild(
std::make_unique<ParsedLiteralExpression>(nullValue, nullValue.toString()));
} else {
listCreation->addChild(transformExpression(*listEntry->oC_Expression()));
}
}
return listCreation;
}
std::unique_ptr<ParsedExpression> Transformer::transformStructLiteral(
CypherParser::IC_StructLiteralContext& ctx) {
auto structPack =
std::make_unique<ParsedFunctionExpression>(StructPackFunctions::name, ctx.getText());
for (auto& structField : ctx.iC_StructField()) {
auto structExpr = transformExpression(*structField->oC_Expression());
std::string paramName;
if (structField->oC_SymbolicName()) {
paramName = transformSymbolicName(*structField->oC_SymbolicName());
} else {
paramName = transformStringLiteral(*structField->StringLiteral());
}
structPack->addOptionalParams(std::move(paramName), std::move(structExpr));
}
return structPack;
}
std::unique_ptr<ParsedExpression> Transformer::transformParameterExpression(
CypherParser::OC_ParameterContext& ctx) {
auto parameterName =
ctx.oC_SymbolicName() ? ctx.oC_SymbolicName()->getText() : ctx.DecimalInteger()->getText();
return std::make_unique<ParsedParameterExpression>(parameterName, ctx.getText());
}
std::unique_ptr<ParsedExpression> Transformer::transformParenthesizedExpression(
CypherParser::OC_ParenthesizedExpressionContext& ctx) {
return transformExpression(*ctx.oC_Expression());
}
std::unique_ptr<ParsedExpression> Transformer::transformFunctionInvocation(
CypherParser::OC_FunctionInvocationContext& ctx) {
if (ctx.STAR()) {
return std::make_unique<ParsedFunctionExpression>(CountStarFunction::name, ctx.getText());
}
std::string functionName;
if (ctx.COUNT()) {
functionName = "COUNT";
} else if (ctx.CAST()) {
functionName = "CAST";
} else {
functionName = transformFunctionName(*ctx.oC_FunctionName());
}
auto expression = std::make_unique<ParsedFunctionExpression>(functionName, ctx.getText(),
ctx.DISTINCT() != nullptr);
if (ctx.CAST()) {
for (auto& functionParameter : ctx.iC_FunctionParameter()) {
expression->addChild(transformFunctionParameterExpression(*functionParameter));
}
if (ctx.iC_DataType()) {
expression->addChild(std::make_unique<ParsedLiteralExpression>(
common::Value(transformDataType(*ctx.iC_DataType()))));
}
} else {
for (auto& functionParameter : ctx.iC_FunctionParameter()) {
auto parsedFunctionParameter = transformFunctionParameterExpression(*functionParameter);
if (functionParameter->oC_SymbolicName()) {
expression->addOptionalParams(
transformSymbolicName(*functionParameter->oC_SymbolicName()),
std::move(parsedFunctionParameter));
} else {
expression->addChild(std::move(parsedFunctionParameter));
}
}
}
return expression;
}
std::string Transformer::transformFunctionName(CypherParser::OC_FunctionNameContext& ctx) {
return transformSymbolicName(*ctx.oC_SymbolicName());
}
std::vector<std::string> Transformer::transformLambdaVariables(
CypherParser::IC_LambdaVarsContext& ctx) {
std::vector<std::string> lambdaVariables;
lambdaVariables.reserve(ctx.oC_SymbolicName().size());
for (auto& var : ctx.oC_SymbolicName()) {
lambdaVariables.push_back(transformSymbolicName(*var));
}
return lambdaVariables;
}
std::unique_ptr<ParsedExpression> Transformer::transformLambdaParameter(
CypherParser::IC_LambdaParameterContext& ctx) {
auto vars = transformLambdaVariables(*ctx.iC_LambdaVars());
auto lambdaOperation = transformExpression(*ctx.oC_Expression());
return std::make_unique<ParsedLambdaExpression>(std::move(vars), std::move(lambdaOperation),
ctx.getText());
}
std::unique_ptr<ParsedExpression> Transformer::transformFunctionParameterExpression(
CypherParser::IC_FunctionParameterContext& ctx) {
if (ctx.iC_LambdaParameter()) {
return transformLambdaParameter(*ctx.iC_LambdaParameter());
} else {
auto expression = transformExpression(*ctx.oC_Expression());
if (ctx.oC_SymbolicName()) {
expression->setAlias(transformSymbolicName(*ctx.oC_SymbolicName()));
}
return expression;
}
}
std::unique_ptr<ParsedExpression> Transformer::transformPathPattern(
CypherParser::OC_PathPatternsContext& ctx) {
auto subquery = std::make_unique<ParsedSubqueryExpression>(SubqueryType::EXISTS, ctx.getText());
auto patternElement = PatternElement(transformNodePattern(*ctx.oC_NodePattern()));
for (auto& chain : ctx.oC_PatternElementChain()) {
patternElement.addPatternElementChain(transformPatternElementChain(*chain));
}
subquery->addPatternElement(std::move(patternElement));
return subquery;
}
std::unique_ptr<ParsedExpression> Transformer::transformExistCountSubquery(
CypherParser::OC_ExistCountSubqueryContext& ctx) {
auto type = ctx.EXISTS() ? SubqueryType::EXISTS : SubqueryType::COUNT;
auto subquery = std::make_unique<ParsedSubqueryExpression>(type, ctx.getText());
subquery->setPatternElements(transformPattern(*ctx.oC_Pattern()));
if (ctx.oC_Where()) {
subquery->setWhereClause(transformWhere(*ctx.oC_Where()));
}
if (ctx.iC_Hint()) {
subquery->setHint(transformJoinHint(*ctx.iC_Hint()->iC_JoinNode()));
}
return subquery;
}
std::unique_ptr<ParsedExpression> Transformer::transformOcQuantifier(
CypherParser::OC_QuantifierContext& ctx) {
auto variable = transformVariable(*ctx.oC_FilterExpression()->oC_IdInColl()->oC_Variable());
auto whereExpr = transformWhere(*ctx.oC_FilterExpression()->oC_Where());
auto lambdaRaw = variable + "->" + whereExpr->toString();
auto lambdaExpr = std::make_unique<ParsedLambdaExpression>(std::vector<std::string>{variable},
std::move(whereExpr), lambdaRaw);
std::string quantifierName;
if (ctx.ALL()) {
quantifierName = "ALL";
} else if (ctx.ANY()) {
quantifierName = "ANY";
} else if (ctx.NONE()) {
quantifierName = "NONE";
} else if (ctx.SINGLE()) {
quantifierName = "SINGLE";
}
auto listExpr = transformExpression(*ctx.oC_FilterExpression()->oC_IdInColl()->oC_Expression());
return std::make_unique<ParsedFunctionExpression>(quantifierName, std::move(listExpr),
std::move(lambdaExpr), ctx.getText());
}
std::unique_ptr<ParsedExpression> Transformer::createPropertyExpression(
CypherParser::OC_PropertyKeyNameContext& ctx, std::unique_ptr<ParsedExpression> child) {
auto key = transformPropertyKeyName(ctx);
return std::make_unique<ParsedPropertyExpression>(key, std::move(child),
child->toString() + "." + key);
}
std::unique_ptr<ParsedExpression> Transformer::createPropertyExpression(
CypherParser::OC_PropertyLookupContext& ctx, std::unique_ptr<ParsedExpression> child) {
auto key =
ctx.STAR() ? InternalKeyword::STAR : transformPropertyKeyName(*ctx.oC_PropertyKeyName());
return std::make_unique<ParsedPropertyExpression>(key, std::move(child),
child->toString() + ctx.getText());
}
std::unique_ptr<ParsedExpression> Transformer::transformCaseExpression(
CypherParser::OC_CaseExpressionContext& ctx) {
std::unique_ptr<ParsedExpression> caseExpression = nullptr;
std::unique_ptr<ParsedExpression> elseExpression = nullptr;
if (ctx.ELSE()) {
if (ctx.oC_Expression().size() == 1) {
elseExpression = transformExpression(*ctx.oC_Expression(0));
} else {
DASSERT(ctx.oC_Expression().size() == 2);
caseExpression = transformExpression(*ctx.oC_Expression(0));
elseExpression = transformExpression(*ctx.oC_Expression(1));
}
} else {
if (ctx.oC_Expression().size() == 1) {
caseExpression = transformExpression(*ctx.oC_Expression(0));
}
}
auto parsedCaseExpression = std::make_unique<ParsedCaseExpression>(ctx.getText());
parsedCaseExpression->setCaseExpression(std::move(caseExpression));
parsedCaseExpression->setElseExpression(std::move(elseExpression));
for (auto& caseAlternative : ctx.oC_CaseAlternative()) {
parsedCaseExpression->addCaseAlternative(transformCaseAlternative(*caseAlternative));
}
return parsedCaseExpression;
}
ParsedCaseAlternative Transformer::transformCaseAlternative(
CypherParser::OC_CaseAlternativeContext& ctx) {
auto whenExpression = transformExpression(*ctx.oC_Expression(0));
auto thenExpression = transformExpression(*ctx.oC_Expression(1));
return ParsedCaseAlternative(std::move(whenExpression), std::move(thenExpression));
}
std::unique_ptr<ParsedExpression> Transformer::transformNumberLiteral(
CypherParser::OC_NumberLiteralContext& ctx, bool negative) {
if (ctx.oC_IntegerLiteral()) {
return transformIntegerLiteral(*ctx.oC_IntegerLiteral(), negative);
} else {
DASSERT(ctx.oC_DoubleLiteral());
return transformDoubleLiteral(*ctx.oC_DoubleLiteral(), negative);
}
}
std::unique_ptr<ParsedExpression> Transformer::transformProperty(
CypherParser::OC_PropertyExpressionContext& ctx) {
auto child = transformAtom(*ctx.oC_Atom());
return createPropertyExpression(*ctx.oC_PropertyLookup(), std::move(child));
}
std::string Transformer::transformPropertyKeyName(CypherParser::OC_PropertyKeyNameContext& ctx) {
return transformSymbolicName(*ctx.oC_SymbolicName());
}
std::unique_ptr<ParsedExpression> Transformer::transformIntegerLiteral(
CypherParser::OC_IntegerLiteralContext& ctx, bool negative) {
auto text = ctx.DecimalInteger()->getText();
if (negative) {
text = '-' + text;
}
string_t literal{text.c_str(), text.length()};
int64_t result = 0;
if (function::CastString::tryCast(literal, result)) {
return std::make_unique<ParsedLiteralExpression>(Value(result), ctx.getText());
}
int128_t result128 = 0;
if (function::trySimpleIntegerCast(reinterpret_cast<const char*>(literal.getData()),
literal.len, result128)) {
return std::make_unique<ParsedLiteralExpression>(Value(result128), ctx.getText());
}
uint128_t resultu128 = 0;
function::CastString::operation(literal, resultu128);
return std::make_unique<ParsedLiteralExpression>(Value(resultu128), ctx.getText());
}
std::unique_ptr<ParsedExpression> Transformer::transformDoubleLiteral(
CypherParser::OC_DoubleLiteralContext& ctx, bool negative) {
auto text = ctx.ExponentDecimalReal() ? ctx.ExponentDecimalReal()->getText() :
ctx.RegularDecimalReal()->getText();
if (negative) {
text = '-' + text;
}
string_t literal{text.c_str(), text.length()};
double result = 0;
function::CastString::operation(literal, result);
return std::make_unique<ParsedLiteralExpression>(Value(result), ctx.getText());
}
} }