You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kexi/kexidb/expression.h

312 lines
10 KiB

/* This file is part of the KDE project
Copyright (C) 2003-2007 Jaroslaw Staniek <js@iidea.pl>
Design based on nexp.h : Parser module of Python-like language
(C) 2001 Jaroslaw Staniek, MIMUW (www.mimuw.edu.pl)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KEXIDB_EXPRESSION_H
#define KEXIDB_EXPRESSION_H
#include "field.h"
#include "queryschema.h"
#include <kdebug.h>
#include "global.h"
namespace KexiDB {
//! classes
#define KexiDBExpr_Unknown 0
#define KexiDBExpr_Unary 1
#define KexiDBExpr_Arithm 2
#define KexiDBExpr_Logical 3
#define KexiDBExpr_Relational 4
#define KexiDBExpr_SpecialBinary 5
#define KexiDBExpr_Const 6
#define KexiDBExpr_Variable 7
#define KexiDBExpr_Function 8
#define KexiDBExpr_Aggregation 9
#define KexiDBExpr_TableList 10
#define KexiDBExpr_QueryParameter 11
//! Custom tokens are not used in parser but used as extension in expression classes.
//#define KEXIDB_CUSTOM_TOKEN 0x1000
//! \return class name of class \a c
KEXI_DB_EXPORT TQString exprClassName(int c);
class ParseInfo;
class NArgExpr;
class UnaryExpr;
class BinaryExpr;
class ConstExpr;
class VariableExpr;
class FunctionExpr;
class QueryParameterExpr;
class QuerySchemaParameterValueListIterator;
//class QuerySchemaParameterList;
//! A base class for all expressions
class KEXI_DB_EXPORT BaseExpr
{
public:
typedef TQPtrList<BaseExpr> List;
typedef TQPtrListIterator<BaseExpr> ListIterator;
BaseExpr(int token);
virtual ~BaseExpr();
//! \return a deep copy of this object.
//! @todo a nonpointer will be returned here when we move to implicit data sharing
virtual BaseExpr* copy() const = 0;
int token() const { return m_token; }
virtual Field::Type type();
BaseExpr* tqparent() const { return m_par; }
virtual void setParent(BaseExpr *p) { m_par = p; }
virtual bool validate(ParseInfo& parseInfo);
/*! \return string as a representation of this expression element by running recursive calls.
\a param, if not 0, points to a list item containing value of a query parameter
(used in QueryParameterExpr). */
virtual TQString toString(QuerySchemaParameterValueListIterator* params = 0) = 0;
/*! Collects query parameters (messages and types) reculsively and saves them to params.
The leaf nodes are objects of QueryParameterExpr class. */
virtual void getQueryParameters(QuerySchemaParameterList& params) = 0;
inline void debug() { KexiDBDbg << debugString() << endl; }
virtual TQString debugString();
/*! \return single character if the token is < 256
or token name, e.g. LESS_OR_EQUAL (for debugging). */
inline TQString tokenToDebugString() { return tokenToDebugString(m_token); }
static TQString tokenToDebugString(int token);
/*! \return string for token, like "<=" or ">" */
virtual TQString tokenToString();
int exprClass() const { return m_cl; }
/*! Convenience type casts. */
NArgExpr* toNArg();
UnaryExpr* toUnary();
BinaryExpr* toBinary();
ConstExpr* toConst();
VariableExpr* toVariable();
FunctionExpr* toFunction();
QueryParameterExpr* toQueryParameter();
protected:
int m_cl; //!< class
BaseExpr *m_par; //!< tqparent expression
int m_token;
};
//! A base class N-argument operation
class KEXI_DB_EXPORT NArgExpr : public BaseExpr
{
public:
NArgExpr(int aClass, int token);
NArgExpr(const NArgExpr& expr);
virtual ~NArgExpr();
//! \return a deep copy of this object.
virtual NArgExpr* copy() const;
void add(BaseExpr *expr);
void prepend(BaseExpr *expr);
BaseExpr *arg(int n);
int args();
virtual TQString debugString();
virtual TQString toString(QuerySchemaParameterValueListIterator* params = 0);
virtual void getQueryParameters(QuerySchemaParameterList& params);
virtual bool validate(ParseInfo& parseInfo);
BaseExpr::List list;
};
//! An unary argument operation: + - NOT (or !) ~ "IS NULL" "IS NOT NULL"
class KEXI_DB_EXPORT UnaryExpr : public BaseExpr
{
public:
UnaryExpr(int token, BaseExpr *arg);
UnaryExpr(const UnaryExpr& expr);
virtual ~UnaryExpr();
//! \return a deep copy of this object.
virtual UnaryExpr* copy() const;
virtual Field::Type type();
virtual TQString debugString();
virtual TQString toString(QuerySchemaParameterValueListIterator* params = 0);
virtual void getQueryParameters(QuerySchemaParameterList& params);
BaseExpr *arg() const { return m_arg; }
virtual bool validate(ParseInfo& parseInfo);
BaseExpr *m_arg;
};
/*! A base class for binary operation
- arithmetic operations: + - / * % << >> & | ||
- relational operations: = (or ==) < > <= >= <> (or !=) LIKE IN 'SIMILAR TO' 'NOT SIMILAR TO'
- logical operations: OR (or ||) AND (or &&) XOR
- SpecialBinary "pseudo operators":
* e.g. "f1 f2" : token == 0
* e.g. "f1 AS f2" : token == AS
*/
class KEXI_DB_EXPORT BinaryExpr : public BaseExpr
{
public:
BinaryExpr(int aClass, BaseExpr *left_expr, int token, BaseExpr *right_expr);
BinaryExpr(const BinaryExpr& expr);
virtual ~BinaryExpr();
//! \return a deep copy of this object.
virtual BinaryExpr* copy() const;
virtual Field::Type type();
virtual TQString debugString();
virtual TQString toString(QuerySchemaParameterValueListIterator* params = 0);
virtual void getQueryParameters(QuerySchemaParameterList& params);
BaseExpr *left() const { return m_larg; }
BaseExpr *right() const { return m_rarg; }
virtual bool validate(ParseInfo& parseInfo);
virtual TQString tokenToString();
BaseExpr *m_larg;
BaseExpr *m_rarg;
};
/*! String, integer, float constants also includes NULL value.
token can be: IDENTIFIER, SQL_NULL, CHARACTER_STRING_LITERAL,
INTEGER_CONST, REAL_CONST */
class KEXI_DB_EXPORT ConstExpr : public BaseExpr
{
public:
ConstExpr(int token, const TQVariant& val);
ConstExpr(const ConstExpr& expr);
virtual ~ConstExpr();
//! \return a deep copy of this object.
virtual ConstExpr* copy() const;
virtual Field::Type type();
virtual TQString debugString();
virtual TQString toString(QuerySchemaParameterValueListIterator* params = 0);
virtual void getQueryParameters(QuerySchemaParameterList& params);
virtual bool validate(ParseInfo& parseInfo);
TQVariant value;
};
//! Query parameter used to getting user input of constant values.
//! It contains a message that is displayed to the user.
class KEXI_DB_EXPORT QueryParameterExpr : public ConstExpr
{
public:
QueryParameterExpr(const TQString& message);
QueryParameterExpr(const QueryParameterExpr& expr);
virtual ~QueryParameterExpr();
//! \return a deep copy of this object.
virtual QueryParameterExpr* copy() const;
virtual Field::Type type();
/*! Sets expected type of the parameter. The default is String.
This method is called from tqparent's expression validate().
This depends on the type of the related expression.
For instance: query "SELECT * FROM cars WHERE name=[enter name]",
"[enter name]" has parameter of the same type as "name" field.
"=" binary expression's validate() will be called for the left side
of the expression and then the right side will have type set to String.
*/
void setType(Field::Type type);
virtual TQString debugString();
virtual TQString toString(QuerySchemaParameterValueListIterator* params = 0);
virtual void getQueryParameters(QuerySchemaParameterList& params);
virtual bool validate(ParseInfo& parseInfo);
protected:
Field::Type m_type;
};
//! Variables like <i>fieldname</i> or <i>tablename</i>.<i>fieldname</i>
class KEXI_DB_EXPORT VariableExpr : public BaseExpr
{
public:
VariableExpr(const TQString& _name);
VariableExpr(const VariableExpr& expr);
virtual ~VariableExpr();
//! \return a deep copy of this object.
virtual VariableExpr* copy() const;
virtual Field::Type type();
virtual TQString debugString();
virtual TQString toString(QuerySchemaParameterValueListIterator* params = 0);
virtual void getQueryParameters(QuerySchemaParameterList& params);
/*! Validation. Sets field, tablePositionForField
and tableForQueryAsterisk members.
See addColumn() in parse.y to see how it's used on column adding. */
virtual bool validate(ParseInfo& parseInfo);
/*! Verbatim name as returned by scanner. */
TQString name;
/* NULL by default. After successful validate() it will point to a field,
if the variable is of a form "tablename.fieldname" or "fieldname",
otherwise (eg. for asterisks) -still NULL.
Only meaningful for column expressions within a query. */
Field *field;
/* -1 by default. After successful validate() it will contain a position of a table
within query that needs to be bound to the field.
This value can be either be -1 if no binding is needed.
This value is used in the Parser to call
QuerySchema::addField(Field* field, int bindToTable);
Only meaningful for column expressions within a query. */
int tablePositionForField;
/*! NULL by default. After successful validate() it will point to a table
that is referenced by asterisk, i.e. "*.tablename".
This is set to NULL if this variable is not an asterisk of that form. */
TableSchema *tableForQueryAsterisk;
};
//! - aggregation functions like SUM, COUNT, MAX, ...
//! - builtin functions like CURRENT_TIME()
//! - user defined functions
class KEXI_DB_EXPORT FunctionExpr : public BaseExpr
{
public:
FunctionExpr(const TQString& _name, NArgExpr* args_ = 0);
FunctionExpr(const FunctionExpr& expr);
virtual ~FunctionExpr();
//! \return a deep copy of this object.
virtual FunctionExpr* copy() const;
virtual Field::Type type();
virtual TQString debugString();
virtual TQString toString(QuerySchemaParameterValueListIterator* params = 0);
virtual void getQueryParameters(QuerySchemaParameterList& params);
virtual bool validate(ParseInfo& parseInfo);
static TQValueList<TQCString> builtInAggregates();
static bool isBuiltInAggregate(const TQCString& fname);
TQString name;
NArgExpr* args;
};
} //namespace KexiDB
#endif