1
0
Fork 0

added canThrow() for Expression

This commit is contained in:
Jan Steemann 2014-08-14 20:20:59 +02:00
parent 19da250191
commit 655d7759bf
11 changed files with 223 additions and 160 deletions

View File

@ -231,44 +231,6 @@ v8::Handle<v8::Value> AqlValue::toV8 (AQL_TRANSACTION_V8* trx,
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief toString method
////////////////////////////////////////////////////////////////////////////////
std::string AqlValue::toString (AQL_TRANSACTION_V8* trx,
TRI_document_collection_t const* document) const {
switch (_type) {
case JSON: {
return _json->toString();
}
case SHAPED: {
// we're lazy and just stringify the json representation
// this does not matter as this code is not performance-sensitive
return toJson(trx, document).toString();
}
case DOCVEC: {
std::stringstream s;
s << "I am a DOCVEC with " << _vector->size() << " blocks.";
return s.str();
}
case RANGE: {
std::stringstream s;
s << "I am a range: " << _range->_low << " .. " << _range->_high;
return s.str();
}
case EMPTY: {
return std::string("empty");
}
}
// should never get here
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson method
////////////////////////////////////////////////////////////////////////////////

View File

@ -163,13 +163,6 @@ namespace triagens {
v8::Handle<v8::Value> toV8 (AQL_TRANSACTION_V8*,
TRI_document_collection_t const*) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief toString method
////////////////////////////////////////////////////////////////////////////////
std::string toString (AQL_TRANSACTION_V8*,
TRI_document_collection_t const*) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson method
////////////////////////////////////////////////////////////////////////////////

View File

@ -333,6 +333,79 @@ bool AstNode::isConstant () const {
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node (and its subnodes) can throw a runtime
/// exception
////////////////////////////////////////////////////////////////////////////////
bool AstNode::canThrow () const {
// check sub-nodes first
size_t const n = numMembers();
for (size_t i = 0; i < n; ++i) {
auto member = getMember(i);
if (member->canThrow()) {
// if any sub-node may throw, the whole branch may throw
return true;
}
}
// no sub-node throws, now check ourselves
if (type == NODE_TYPE_OPERATOR_UNARY_PLUS ||
type == NODE_TYPE_OPERATOR_UNARY_MINUS ||
type == NODE_TYPE_OPERATOR_UNARY_NOT) {
// all unary operators may throw
return true;
}
if (type == NODE_TYPE_OPERATOR_BINARY_AND ||
type == NODE_TYPE_OPERATOR_BINARY_OR) {
// the logical operators can throw
return true;
}
if (type == NODE_TYPE_OPERATOR_BINARY_PLUS ||
type == NODE_TYPE_OPERATOR_BINARY_MINUS ||
type == NODE_TYPE_OPERATOR_BINARY_TIMES ||
type == NODE_TYPE_OPERATOR_BINARY_DIV ||
type == NODE_TYPE_OPERATOR_BINARY_MOD) {
// the arithmetic operators can throw
return true;
}
if (type == NODE_TYPE_OPERATOR_BINARY_IN) {
// the IN operator can throw (if rhs is not a list)
return true;
}
if (type == NODE_TYPE_OPERATOR_TERNARY) {
return true;
}
if (type == NODE_TYPE_INDEXED_ACCESS) {
// TODO: validate whether this can actually throw
return true;
}
if (type == NODE_TYPE_EXPAND) {
// TODO: validate whether this can actually throw
return true;
}
if (type == NODE_TYPE_FCALL) {
// built-in functions may or may not throw
auto func = static_cast<Function*>(getData());
return func->canThrow;
}
if (type == NODE_TYPE_FCALL_USER) {
// user functions can always throw
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the type name of a node
////////////////////////////////////////////////////////////////////////////////
@ -429,8 +502,6 @@ std::string AstNode::typeString () const {
return "collection";
case NODE_TYPE_REFERENCE:
return "reference";
case NODE_TYPE_ATTRIBUTE:
return "attribute";
case NODE_TYPE_PARAMETER:
return "parameter";
case NODE_TYPE_FCALL:

View File

@ -120,7 +120,6 @@ namespace triagens {
NODE_TYPE_ARRAY_ELEMENT,
NODE_TYPE_COLLECTION,
NODE_TYPE_REFERENCE,
NODE_TYPE_ATTRIBUTE,
NODE_TYPE_PARAMETER,
NODE_TYPE_FCALL,
NODE_TYPE_FCALL_USER,
@ -212,6 +211,13 @@ namespace triagens {
bool isConstant () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node (and its subnodes) may throw a runtime
/// exception
////////////////////////////////////////////////////////////////////////////////
bool canThrow () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief return the number of members
////////////////////////////////////////////////////////////////////////////////

View File

@ -1900,7 +1900,8 @@ AqlItemBlock* RemoveBlock::getSome (size_t atLeast,
if (ep->_outVariable == nullptr) {
// don't return anything
// loop until input is exhausted
// loop over input until it is exhausted
while (true) {
auto res = ExecutionBlock::getSome(atLeast, atMost);
@ -1939,6 +1940,8 @@ AqlItemBlock* RemoveBlock::getSome (size_t atLeast,
throw;
}
}
// will never get here
}
// NOT YET IMPLEMENTED

View File

@ -675,7 +675,6 @@ ExecutionNode* ExecutionPlan::fromNode (Ast const* ast,
}
case NODE_TYPE_REMOVE: {
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
en = fromNodeRemove(ast, en, member);
break;
}

View File

@ -56,7 +56,8 @@ Expression::Expression (V8Executor* executor,
AstNode const* node)
: _executor(executor),
_node(node),
_type(UNPROCESSED) {
_type(UNPROCESSED),
_canThrow(true) {
TRI_ASSERT(_executor != nullptr);
TRI_ASSERT(_node != nullptr);
@ -149,15 +150,20 @@ void Expression::analyzeExpression () {
}
_type = JSON;
_canThrow = false;
}
else if (_node->isSimple()) {
_type = SIMPLE;
_canThrow = _node->canThrow();
}
else {
// generate a V8 expression
_func = _executor->generateExpression(_node);
_type = V8;
_canThrow = _node->canThrow();
}
std::cout << "CAN THROW: " << _canThrow << "\n";
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -93,6 +93,14 @@ namespace triagens {
return _node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the expression can throw an exception
////////////////////////////////////////////////////////////////////////////////
inline bool canThrow () const {
return _canThrow;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief clone the expression, needed to clone execution plans
////////////////////////////////////////////////////////////////////////////////
@ -187,6 +195,12 @@ namespace triagens {
ExpressionType _type;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the expression may throw a runtime exception
////////////////////////////////////////////////////////////////////////////////
bool _canThrow;
};
} // namespace triagens::aql

View File

@ -42,10 +42,12 @@ using namespace triagens::aql;
Function::Function (std::string const& name,
std::string const& arguments,
bool isDeterministic)
bool isDeterministic,
bool canThrow)
: name(name),
arguments(arguments),
isDeterministic(isDeterministic),
canThrow(canThrow),
containsCollectionParameter(false) {
initArguments();

View File

@ -49,6 +49,7 @@ namespace triagens {
Function (std::string const&,
std::string const&,
bool,
bool);
////////////////////////////////////////////////////////////////////////////////
@ -115,6 +116,12 @@ namespace triagens {
bool const isDeterministic;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the function may throw a runtime exception
////////////////////////////////////////////////////////////////////////////////
bool const canThrow;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the function contains a collection parameter that
/// will cause some special conversion during function calls

View File

@ -88,134 +88,134 @@ std::unordered_map<std::string, Function const> const V8Executor::FunctionNames{
// r = regex (a string with a special format). note: the regex type is mutually exclusive with all other types
// type check functions
{ "IS_NULL", Function("IS_NULL", ".", true) },
{ "IS_BOOL", Function("IS_BOOL", ".", true) },
{ "IS_NUMBER", Function("IS_NUMBER", ".", true) },
{ "IS_STRING", Function("IS_STRING", ".", true) },
{ "IS_LIST", Function("IS_LIST", ".", true) },
{ "IS_DOCUMENT", Function("IS_DOCUMENT", ".", true) },
{ "IS_NULL", Function("IS_NULL", ".", true, false) },
{ "IS_BOOL", Function("IS_BOOL", ".", true, false) },
{ "IS_NUMBER", Function("IS_NUMBER", ".", true, false) },
{ "IS_STRING", Function("IS_STRING", ".", true, false) },
{ "IS_LIST", Function("IS_LIST", ".", true, false) },
{ "IS_DOCUMENT", Function("IS_DOCUMENT", ".", true, false) },
// type cast functions
{ "TO_NUMBER", Function("CAST_NUMBER", ".", true) },
{ "TO_STRING", Function("CAST_STRING", ".", true) },
{ "TO_BOOL", Function("CAST_BOOL", ".", true) },
{ "TO_LIST", Function("CAST_LIST", ".", true) },
{ "TO_NUMBER", Function("CAST_NUMBER", ".", true, false) },
{ "TO_STRING", Function("CAST_STRING", ".", true, false) },
{ "TO_BOOL", Function("CAST_BOOL", ".", true, false) },
{ "TO_LIST", Function("CAST_LIST", ".", true, false) },
// string functions
{ "CONCAT", Function("STRING_CONCAT", "sz,sz|+", true) },
{ "CONCAT_SEPARATOR", Function("STRING_CONCAT_SEPARATOR", "s,sz,sz|+", true) },
{ "CHAR_LENGTH", Function("CHAR_LENGTH", "s", true) },
{ "LOWER", Function("STRING_LOWER", "s", true) },
{ "UPPER", Function("STRING_UPPER", "s", true) },
{ "SUBSTRING", Function("STRING_SUBSTRING", "s,n|n", true) },
{ "CONTAINS", Function("STRING_CONTAINS", "s,s|b", true) },
{ "LIKE", Function("STRING_LIKE", "s,r|b", true) },
{ "LEFT", Function("STRING_LEFT", "s,n", true) },
{ "RIGHT", Function("STRING_RIGHT", "s,n", true) },
{ "TRIM", Function("STRING_TRIM", "s|n", true) },
{ "CONCAT", Function("STRING_CONCAT", "sz,sz|+", true, true) },
{ "CONCAT_SEPARATOR", Function("STRING_CONCAT_SEPARATOR", "s,sz,sz|+", true, true) },
{ "CHAR_LENGTH", Function("CHAR_LENGTH", "s", true, true) },
{ "LOWER", Function("STRING_LOWER", "s", true, true) },
{ "UPPER", Function("STRING_UPPER", "s", true, true) },
{ "SUBSTRING", Function("STRING_SUBSTRING", "s,n|n", true, true) },
{ "CONTAINS", Function("STRING_CONTAINS", "s,s|b", true, true) },
{ "LIKE", Function("STRING_LIKE", "s,r|b", true, true) },
{ "LEFT", Function("STRING_LEFT", "s,n", true, true) },
{ "RIGHT", Function("STRING_RIGHT", "s,n", true, true) },
{ "TRIM", Function("STRING_TRIM", "s|n", true, true) },
// numeric functions
{ "FLOOR", Function("NUMBER_FLOOR", "n", true) },
{ "CEIL", Function("NUMBER_CEIL", "n", true) },
{ "ROUND", Function("NUMBER_ROUND", "n", true) },
{ "ABS", Function("NUMBER_ABS", "n", true) },
{ "RAND", Function("NUMBER_RAND", "", false) },
{ "SQRT", Function("NUMBER_SQRT", "n", true) },
{ "FLOOR", Function("NUMBER_FLOOR", "n", true, true) },
{ "CEIL", Function("NUMBER_CEIL", "n", true, true) },
{ "ROUND", Function("NUMBER_ROUND", "n", true, true) },
{ "ABS", Function("NUMBER_ABS", "n", true, true) },
{ "RAND", Function("NUMBER_RAND", "", false, true) },
{ "SQRT", Function("NUMBER_SQRT", "n", true, true) },
// list functions
{ "RANGE", Function("RANGE", "n,n|n", true) },
{ "UNION", Function("UNION", "l,l|+",true) },
{ "UNION_DISTINCT", Function("UNION_DISTINCT", "l,l|+", true) },
{ "MINUS", Function("MINUS", "l,l|+", true) },
{ "INTERSECTION", Function("INTERSECTION", "l,l|+", true) },
{ "FLATTEN", Function("FLATTEN", "l|n", true) },
{ "LENGTH", Function("LENGTH", "las", true) },
{ "MIN", Function("MIN", "l", true) },
{ "MAX", Function("MAX", "l", true) },
{ "SUM", Function("SUM", "l", true) },
{ "MEDIAN", Function("MEDIAN", "l", true) },
{ "AVERAGE", Function("AVERAGE", "l", true) },
{ "VARIANCE_SAMPLE", Function("VARIANCE_SAMPLE", "l", true) },
{ "VARIANCE_POPULATION", Function("VARIANCE_POPULATION", "l", true) },
{ "STDDEV_SAMPLE", Function("STDDEV_SAMPLE", "l", true) },
{ "STDDEV_POPULATION", Function("STDDEV_POPULATION", "l", true) },
{ "UNIQUE", Function("UNIQUE", "l", true) },
{ "SLICE", Function("SLICE", "l,n|n", true) },
{ "REVERSE", Function("REVERSE", "ls", true) }, // note: REVERSE() can be applied on strings, too
{ "FIRST", Function("FIRST", "l", true) },
{ "LAST", Function("LAST", "l", true) },
{ "NTH", Function("NTH", "l,n", true) },
{ "POSITION", Function("POSITION", "l,.|b", true) },
{ "RANGE", Function("RANGE", "n,n|n", true, true) },
{ "UNION", Function("UNION", "l,l|+",true, true) },
{ "UNION_DISTINCT", Function("UNION_DISTINCT", "l,l|+", true, true) },
{ "MINUS", Function("MINUS", "l,l|+", true, true) },
{ "INTERSECTION", Function("INTERSECTION", "l,l|+", true, true) },
{ "FLATTEN", Function("FLATTEN", "l|n", true, true) },
{ "LENGTH", Function("LENGTH", "las", true, true) },
{ "MIN", Function("MIN", "l", true, true) },
{ "MAX", Function("MAX", "l", true, true) },
{ "SUM", Function("SUM", "l", true, true) },
{ "MEDIAN", Function("MEDIAN", "l", true, true) },
{ "AVERAGE", Function("AVERAGE", "l", true, true) },
{ "VARIANCE_SAMPLE", Function("VARIANCE_SAMPLE", "l", true, true) },
{ "VARIANCE_POPULATION", Function("VARIANCE_POPULATION", "l", true, true) },
{ "STDDEV_SAMPLE", Function("STDDEV_SAMPLE", "l", true, true) },
{ "STDDEV_POPULATION", Function("STDDEV_POPULATION", "l", true, true) },
{ "UNIQUE", Function("UNIQUE", "l", true, true) },
{ "SLICE", Function("SLICE", "l,n|n", true, true) },
{ "REVERSE", Function("REVERSE", "ls", true, true) }, // note: REVERSE() can be applied on strings, too
{ "FIRST", Function("FIRST", "l", true, true) },
{ "LAST", Function("LAST", "l", true, true) },
{ "NTH", Function("NTH", "l,n", true, true) },
{ "POSITION", Function("POSITION", "l,.|b", true, true) },
// document functions
{ "HAS", Function("HAS", "az,s", true) },
{ "ATTRIBUTES", Function("ATTRIBUTES", "a|b,b", true) },
{ "MERGE", Function("MERGE", "a,a|+", true) },
{ "MERGE_RECURSIVE", Function("MERGE_RECURSIVE", "a,a|+", true) },
{ "DOCUMENT", Function("DOCUMENT", "h.|.", true) },
{ "MATCHES", Function("MATCHES", ".,l|b", true) },
{ "UNSET", Function("UNSET", "a,sl|+", true) },
{ "KEEP", Function("KEEP", "a,sl|+", true) },
{ "TRANSLATE", Function("TRANSLATE", ".,a|.", true) },
{ "HAS", Function("HAS", "az,s", true, true) },
{ "ATTRIBUTES", Function("ATTRIBUTES", "a|b,b", true, true) },
{ "MERGE", Function("MERGE", "a,a|+", true, true) },
{ "MERGE_RECURSIVE", Function("MERGE_RECURSIVE", "a,a|+", true, true) },
{ "DOCUMENT", Function("DOCUMENT", "h.|.", true, true) },
{ "MATCHES", Function("MATCHES", ".,l|b", true, true) },
{ "UNSET", Function("UNSET", "a,sl|+", true, true) },
{ "KEEP", Function("KEEP", "a,sl|+", true, true) },
{ "TRANSLATE", Function("TRANSLATE", ".,a|.", true, true) },
// geo functions
{ "NEAR", Function("GEO_NEAR", "h,n,n|nz,s", false) },
{ "WITHIN", Function("GEO_WITHIN", "h,n,n,n|s", false) },
{ "NEAR", Function("GEO_NEAR", "h,n,n|nz,s", false, true) },
{ "WITHIN", Function("GEO_WITHIN", "h,n,n,n|s", false, true) },
// fulltext functions
{ "FULLTEXT", Function("FULLTEXT", "h,s,s", false) },
{ "FULLTEXT", Function("FULLTEXT", "h,s,s", false, true) },
// graph functions
{ "PATHS", Function("GRAPH_PATHS", "c,h|s,b", false )},
{ "GRAPH_PATHS", Function("GENERAL_GRAPH_PATHS", "s|a", false )},
{ "SHORTEST_PATH", Function("GRAPH_SHORTEST_PATH", "h,h,s,s,s|a", false )},
{ "GRAPH_SHORTEST_PATH", Function("GENERAL_GRAPH_SHORTEST_PATH", "s,als,als|a", false )},
{ "GRAPH_DISTANCE_TO", Function("GENERAL_GRAPH_DISTANCE_TO", "s,als,als|a", false )},
{ "TRAVERSAL", Function("GRAPH_TRAVERSAL", "h,h,s,s|a", false )},
{ "GRAPH_TRAVERSAL", Function("GENERAL_GRAPH_TRAVERSAL", "s,als,s|a", false )},
{ "TRAVERSAL_TREE", Function("GRAPH_TRAVERSAL_TREE", "h,h,s,s,s|a", false )},
{ "GRAPH_TRAVERSAL_TREE", Function("GENERAL_GRAPH_TRAVERSAL_TREE", "s,als,s,s|a", false )},
{ "EDGES", Function("GRAPH_EDGES", "h,s,s|l", false )},
{ "GRAPH_EDGES", Function("GENERAL_GRAPH_EDGES", "s,als|a", false )},
{ "GRAPH_VERTICES", Function("GENERAL_GRAPH_VERTICES", "s,als|a", false )},
{ "NEIGHBORS", Function("GRAPH_NEIGHBORS", "h,h,s,s|l", false )},
{ "GRAPH_NEIGHBORS", Function("GENERAL_GRAPH_NEIGHBORS", "s,als|a", false )},
{ "GRAPH_COMMON_NEIGHBORS", Function("GENERAL_GRAPH_COMMON_NEIGHBORS", "s,als,als|a,a", false )},
{ "GRAPH_COMMON_PROPERTIES", Function("GENERAL_GRAPH_COMMON_PROPERTIES", "s,als,als|a", false )},
{ "GRAPH_ECCENTRICITY", Function("GENERAL_GRAPH_ECCENTRICITY", "s|a", false )},
{ "GRAPH_BETWEENNESS", Function("GENERAL_GRAPH_BETWEENNESS", "s|a", false )},
{ "GRAPH_CLOSENESS", Function("GENERAL_GRAPH_CLOSENESS", "s|a", false )},
{ "GRAPH_ABSOLUTE_ECCENTRICITY", Function("GENERAL_GRAPH_ABSOLUTE_ECCENTRICITY", "s,als|a", false )},
{ "GRAPH_ABSOLUTE_BETWEENNESS", Function("GENERAL_GRAPH_ABSOLUTE_BETWEENNESS", "s,als|a", false)},
{ "GRAPH_ABSOLUTE_CLOSENESS", Function("GENERAL_GRAPH_ABSOLUTE_CLOSENESS", "s,als|a", false )},
{ "GRAPH_DIAMETER", Function("GENERAL_GRAPH_DIAMETER", "s|a", false )},
{ "GRAPH_RADIUS", Function("GENERAL_GRAPH_RADIUS", "s|a", false )},
{ "PATHS", Function("GRAPH_PATHS", "c,h|s,b", false, true) },
{ "GRAPH_PATHS", Function("GENERAL_GRAPH_PATHS", "s|a", false, true) },
{ "SHORTEST_PATH", Function("GRAPH_SHORTEST_PATH", "h,h,s,s,s|a", false, true) },
{ "GRAPH_SHORTEST_PATH", Function("GENERAL_GRAPH_SHORTEST_PATH", "s,als,als|a", false, true) },
{ "GRAPH_DISTANCE_TO", Function("GENERAL_GRAPH_DISTANCE_TO", "s,als,als|a", false, true) },
{ "TRAVERSAL", Function("GRAPH_TRAVERSAL", "h,h,s,s|a", false, true) },
{ "GRAPH_TRAVERSAL", Function("GENERAL_GRAPH_TRAVERSAL", "s,als,s|a", false, true) },
{ "TRAVERSAL_TREE", Function("GRAPH_TRAVERSAL_TREE", "h,h,s,s,s|a", false, true) },
{ "GRAPH_TRAVERSAL_TREE", Function("GENERAL_GRAPH_TRAVERSAL_TREE", "s,als,s,s|a", false, true) },
{ "EDGES", Function("GRAPH_EDGES", "h,s,s|l", false, true) },
{ "GRAPH_EDGES", Function("GENERAL_GRAPH_EDGES", "s,als|a", false, true) },
{ "GRAPH_VERTICES", Function("GENERAL_GRAPH_VERTICES", "s,als|a", false, true) },
{ "NEIGHBORS", Function("GRAPH_NEIGHBORS", "h,h,s,s|l", false, true) },
{ "GRAPH_NEIGHBORS", Function("GENERAL_GRAPH_NEIGHBORS", "s,als|a", false, true) },
{ "GRAPH_COMMON_NEIGHBORS", Function("GENERAL_GRAPH_COMMON_NEIGHBORS", "s,als,als|a,a", false, true) },
{ "GRAPH_COMMON_PROPERTIES", Function("GENERAL_GRAPH_COMMON_PROPERTIES", "s,als,als|a", false, true) },
{ "GRAPH_ECCENTRICITY", Function("GENERAL_GRAPH_ECCENTRICITY", "s|a", false, true) },
{ "GRAPH_BETWEENNESS", Function("GENERAL_GRAPH_BETWEENNESS", "s|a", false, true) },
{ "GRAPH_CLOSENESS", Function("GENERAL_GRAPH_CLOSENESS", "s|a", false, true) },
{ "GRAPH_ABSOLUTE_ECCENTRICITY", Function("GENERAL_GRAPH_ABSOLUTE_ECCENTRICITY", "s,als|a", false, true) },
{ "GRAPH_ABSOLUTE_BETWEENNESS", Function("GENERAL_GRAPH_ABSOLUTE_BETWEENNESS", "s,als|a", false, true) },
{ "GRAPH_ABSOLUTE_CLOSENESS", Function("GENERAL_GRAPH_ABSOLUTE_CLOSENESS", "s,als|a", false, true) },
{ "GRAPH_DIAMETER", Function("GENERAL_GRAPH_DIAMETER", "s|a", false, true) },
{ "GRAPH_RADIUS", Function("GENERAL_GRAPH_RADIUS", "s|a", false, true) },
// date functions
{ "DATE_NOW", Function("DATE_NOW", "", false) },
{ "DATE_TIMESTAMP", Function("DATE_TIMESTAMP", "ns|ns,ns,ns,ns,ns,ns", true) },
{ "DATE_ISO8601", Function("DATE_ISO8601", "ns|ns,ns,ns,ns,ns,ns", true) },
{ "DATE_DAYOFWEEK", Function("DATE_DAYOFWEEK", "ns", true) },
{ "DATE_YEAR", Function("DATE_YEAR", "ns", true) },
{ "DATE_MONTH", Function("DATE_MONTH", "ns", true) },
{ "DATE_DAY", Function("DATE_DAY", "ns", true) },
{ "DATE_HOUR", Function("DATE_HOUR", "ns", true) },
{ "DATE_MINUTE", Function("DATE_MINUTE", "ns", true) },
{ "DATE_SECOND", Function("DATE_SECOND", "ns", true) },
{ "DATE_MILLISECOND", Function("DATE_MILLISECOND", "ns", true) },
{ "DATE_NOW", Function("DATE_NOW", "", false, false) },
{ "DATE_TIMESTAMP", Function("DATE_TIMESTAMP", "ns|ns,ns,ns,ns,ns,ns", true, true) },
{ "DATE_ISO8601", Function("DATE_ISO8601", "ns|ns,ns,ns,ns,ns,ns", true, true) },
{ "DATE_DAYOFWEEK", Function("DATE_DAYOFWEEK", "ns", true, true) },
{ "DATE_YEAR", Function("DATE_YEAR", "ns", true, true) },
{ "DATE_MONTH", Function("DATE_MONTH", "ns", true, true) },
{ "DATE_DAY", Function("DATE_DAY", "ns", true, true) },
{ "DATE_HOUR", Function("DATE_HOUR", "ns", true, true) },
{ "DATE_MINUTE", Function("DATE_MINUTE", "ns", true, true) },
{ "DATE_SECOND", Function("DATE_SECOND", "ns", true, true) },
{ "DATE_MILLISECOND", Function("DATE_MILLISECOND", "ns", true, true) },
// misc functions
{ "FAIL", Function("FAIL", "|s", false) },
{ "PASSTHRU", Function("PASSTHRU", ".", false) },
{ "SLEEP", Function("SLEEP", "n", false) },
{ "COLLECTIONS", Function("COLLECTIONS", "", false) },
{ "NOT_NULL", Function("NOT_NULL", ".|+", true) },
{ "FIRST_LIST", Function("FIRST_LIST", ".|+", true) },
{ "FIRST_DOCUMENT", Function("FIRST_DOCUMENT", ".|+", true) },
{ "PARSE_IDENTIFIER", Function("PARSE_IDENTIFIER", ".", true) },
{ "SKIPLIST", Function("SKIPLIST_QUERY", "h,a|n,n", false) },
{ "CURRENT_USER", Function("CURRENT_USER", "", false) },
{ "CURRENT_DATABASE", Function("CURRENT_DATABASE", "", false) }
{ "FAIL", Function("FAIL", "|s", false, true) },
{ "PASSTHRU", Function("PASSTHRU", ".", false, true) },
{ "SLEEP", Function("SLEEP", "n", false, false) },
{ "COLLECTIONS", Function("COLLECTIONS", "", false, true) },
{ "NOT_NULL", Function("NOT_NULL", ".|+", true, true) },
{ "FIRST_LIST", Function("FIRST_LIST", ".|+", true, false) },
{ "FIRST_DOCUMENT", Function("FIRST_DOCUMENT", ".|+", true, false) },
{ "PARSE_IDENTIFIER", Function("PARSE_IDENTIFIER", ".", true, true) },
{ "SKIPLIST", Function("SKIPLIST_QUERY", "h,a|n,n", false, true) },
{ "CURRENT_USER", Function("CURRENT_USER", "", false, false) },
{ "CURRENT_DATABASE", Function("CURRENT_DATABASE", "", false, false) }
};
// -----------------------------------------------------------------------------