00001
#ifndef EXPRESSION_H
00002
#define EXPRESSION_H
00003
00004
#include <NMSTL/util>
00005
#include <NMSTL/ptr>
00006
#include <antlr/SemanticException.hpp>
00007
00008
#include "EString.h"
00009
#include "TupleDescription.h"
00010
#include "Exceptions.h"
00011
#include "Registry.h"
00012
#include "Timestamp.h"
00013
00014
00015
00016
00017
00018
#ifdef TRUE
00019
#undef TRUE
00020
#endif
00021
00022
#ifdef FALSE
00023
#undef FALSE
00024
#endif
00025
00026
using namespace std;
00027
using namespace NMSTL;
00028
00029
BOREALIS_NAMESPACE_BEGIN
00030
00031
AURORA_EXCEPTION_TYPE( ExprException );
00032
AURORA_EXCEPTION_TYPE( EvalException );
00033
00034
00035
00044 class ExprContext
00045 {
00046
public:
00047
00048
static const string
to_string( DataType t );
00049
00054 TupleDescription
getTupleDescription()
const {
return _desc; }
00055
00057 void setTupleDescription(TupleDescription desc) { _desc = desc; }
00058
00061 void getNamedTupleInfo( string name,
00062 TupleDescription &desc,
00063
unsigned int &index
00064 )
const
00065
{
00066 pair<TupleDescription, unsigned int> info = lookup(_named_desc, name);
00067 desc = info.first;
00068 index = info.second;
00069 }
00070
00071
00073 void setNamedTupleInfo(string name, TupleDescription desc,
unsigned int index) {
00074 _named_desc[name] = make_pair(desc, index);
00075 }
00076
00077
00081 void findFieldName( string field_name,
00082 string &tuple_name,
00083
unsigned int &tuple_index,
00084 TupleDescription &tuple_desc,
00085
unsigned int &field_index
00086 )
const
00087
throw( ExprException )
00088 {
00089
bool found =
false;
00090
00091
for ( NamedDesc::const_iterator i = _named_desc.begin();
00092 i != _named_desc.end(); ++i)
00093 {
00094
int off = i->second.first.indexOfField( field_name );
00095
00096
if ( off >= 0 )
00097 {
if ( found )
00098 {
Throw(ExprException,
"multiple fields " + field_name +
" in input tuple(s)");
00099 }
00100
00101 found =
true;
00102
00103 tuple_name = i->first;
00104 tuple_index = i->second.second;
00105 tuple_desc = i->second.first;
00106 field_index = off;
00107 }
00108 }
00109
00110
if ( !found )
00111 {
Throw(ExprException,
"no field " + field_name +
" in any input tuple");
00112 }
00113 }
00114
00115
private:
00116 TupleDescription _desc;
00117
00118
typedef map<string, pair<TupleDescription, unsigned int> > NamedDesc;
00119 NamedDesc _named_desc;
00120
00121
00122 };
00123
00124
00125
00138 class EvalContext {
00139
public:
00145 EvalContext(
unsigned int num_tuples = 1,
00146
unsigned int pool_size = EStringPool::DEFAULT_INITIAL_SIZE) :
00147 _tuple(num_tuples), _pool(pool_size)
00148 {}
00149
00153 void reset() {
00154 _pool.
reset();
00155 }
00156
00158 void setTuple(
const void *tuple) { _tuple[0] = tuple; }
00159
00161 void setTuple(
unsigned int index,
const void *tuple)
00162 {
00163 ASSERT(index < _tuple.size());
00164 _tuple[index] = tuple;
00165 }
00166
00168 const char *
getTuple(
unsigned int index = 0)
const
00169
{
00170 ASSERT(index < _tuple.size());
00171
return static_cast<const char*>(_tuple[index]);
00172 }
00173
00176 char *
alloc(
unsigned int size)
const
00177
{
00178
return _pool.
alloc(size);
00179 }
00180
00182 EStringPool&
getPool()
const
00183
{
00184
return _pool;
00185 }
00186
00187
private:
00188 vector<const void*> _tuple;
00189
mutable EStringPool _pool;
00190
00191
EvalContext(
const EvalContext&);
00192
EvalContext& operator = (
const EvalContext&);
00193
00194
00195 };
00196
00197
00198
00199
00200
template<
class T>
class EvalAs;
00201
00204 template<>
class EvalAs<int32> {};
00205
00208 template<>
class EvalAs<int64> {};
00209
00212 template<>
class EvalAs<single> {};
00213
00216 template<>
class EvalAs<double> {};
00217
00220 template<>
class EvalAs<bool> {};
00221
00224 template<>
class EvalAs<EString> {};
00225
00229 template<>
class EvalAs<string> {};
00230
00234 template<>
class EvalAs<Timestamp> {};
00235
00262 class Expression
00263 {
00264
public:
00265
00266
00267
00268
00270 virtual ~Expression() {}
00271
00274
template<
typename T>
00275 T
eval(
const EvalContext &ctxt )
throw( EvalException )
00276 {
00277
return(
evalImpl( EvalAs<T>(), ctxt ));
00278 }
00279
00282 template<
typename T>
bool is()
const
00283
{
00284
return(
isImpl( EvalAs<T>() ));
00285 }
00286
00289 virtual int32
getStringLength()
const {
return -1; }
00290
00292 int32
getLength()
const
00293
{
00294
if ( _type == DataType::INT )
return sizeof( int32 );
00295
else if ( _type == DataType::LONG )
return sizeof( int64 );
00296
else if ( _type == DataType::FLOAT )
return sizeof( single );
00297
else if ( _type == DataType::SINGLE )
return sizeof( single );
00298
else if ( _type == DataType::DOUBLE )
return sizeof(
double );
00299
else if ( _type == DataType::BOOL )
return sizeof(
bool );
00300
else if ( _type == DataType::TIMESTAMP )
return sizeof( Timestamp );
00301
else
00302
return(
getStringLength() );
00303 }
00304
00307 void evalInto(
char *buf,
const EvalContext& ctxt)
throw (EvalException)
00308 {
00309 ASSERT(
getLength() != -1 );
00310
00311
if ( _type == DataType::INT ) *(int32*)buf = eval<int32>(ctxt);
00312
else if ( _type == DataType::LONG ) *(int64*)buf = eval<int64>(ctxt);
00313
else if ( _type == DataType::FLOAT ) *(single*)buf = eval<single>(ctxt);
00314
else if ( _type == DataType::SINGLE ) *(single*)buf = eval<single>(ctxt);
00315
else if ( _type == DataType::DOUBLE ) *(
double*)buf = eval<double>(ctxt);
00316
else if ( _type == DataType::BOOL ) *(
bool*)buf = eval<bool>(ctxt);
00317
else if ( _type == DataType::TIMESTAMP ) *( Timestamp* )buf = eval<Timestamp>(ctxt);
00318
else {
00319 EString str = eval<EString>(ctxt);
00320 __builtin_memcpy( buf, str.
data(), str.
length() );
00321
00322
int len =
getStringLength();
00323 ASSERT( len >= 0 );
00324 ASSERT( str.
length() <= (
unsigned int)len );
00325 __builtin_memset( buf + str.
length(), 0, len - str.
length() );
00326 }
00327 }
00328
00331 virtual bool is_numeric()
const {
return( is<double>() ); }
00332
00334 DataType
getType()
const {
return _type; }
00335
00338 TupleDescription::Field
getField(string name = string())
const throw (ExprException);
00339
00341 virtual void dump( string& s,
unsigned int indent = 0 )
const
00342
{
00343
for (
unsigned int i = 0; i < indent; ++i )
00344 { s +=
" ";
00345 }
00346
00347 s <<
typeid( *this );
00348
00349 string val =
value();
00350
if ( !val.empty() )
00351 { s <<
" - " << val;
00352 }
00353
00354 s <<
"\n";
00355
00356
dump_children( s, indent + 1 );
00357 }
00358
00360 string
as_string()
const
00361
{
00362
return( ::to_string(
typeid( *this )));
00363 }
00364
00366
static ptr<Expression>
parse( string expr,
const ExprContext &ctxt )
00367
throw( ExprException );
00368
00373
static void evalVectorInto(
const vector<ptr<Expression> > &exprs,
00374
char *buf,
const EvalContext &ctxt )
00375
throw( EvalException );
00376
00381
static ptr<Expression>
makeFieldExpresssion( string tuple_name,
00382 string field_name,
00383
const ExprContext &ctxt
00384 )
00385
throw( ExprException );
00386
00388 TupleDescription::Field
toField( string name )
const
00389
throw(
AuroraException );
00390
00391
protected:
00392 Expression( DataType type ) : _type(type) {}
00393
00394
protected:
00396 virtual bool evalImpl( EvalAs<bool>,
const EvalContext& )
00397 throw( EvalException )
00398 {
00399
throw EvalException(
"Cannot coerce result of "
00400 + ::
to_string(
typeid( *
this )) +
" to bool" );
00401 }
00402
00404 virtual bool isImpl( EvalAs<bool> )
const {
return(
false ); }
00405
00406
00408 virtual int32
evalImpl( EvalAs<int32>,
const EvalContext& )
00409 throw( EvalException )
00410 {
00411
throw EvalException(
"Cannot coerce result of "
00412 + ::
to_string(
typeid( *
this )) +
" to int" );
00413 }
00414
00416 virtual bool isImpl( EvalAs<int32> )
const {
return(
false ); }
00417
00418
00420 virtual int64
evalImpl( EvalAs<int64>,
const EvalContext& )
00421 throw( EvalException )
00422 {
00423
throw EvalException(
"Cannot coerce result of "
00424 + ::
to_string(
typeid( *
this )) +
" to long" );
00425 }
00426
00428 virtual bool isImpl( EvalAs<int64> )
const {
return(
false ); }
00429
00430
00432 virtual single
evalImpl( EvalAs<single>,
const EvalContext& )
00433 throw( EvalException )
00434 {
00435
throw EvalException(
"Cannot coerce result of "
00436 + ::
to_string(
typeid( *
this )) +
" to single" );
00437 }
00438
00440 virtual bool isImpl( EvalAs<single> )
const {
return(
false ); }
00441
00442
00444 virtual double evalImpl( EvalAs<double>,
const EvalContext& )
00445 throw( EvalException )
00446 {
00447
throw EvalException(
"Cannot coerce result of "
00448 + ::
to_string(
typeid( *
this )) +
" to double" );
00449 }
00450
00452 virtual bool isImpl( EvalAs<double> )
const {
return(
false ); }
00453
00454
00456 virtual EString
evalImpl( EvalAs<EString>,
const EvalContext& )
00457 throw( EvalException )
00458 {
00459
throw EvalException(
"Cannot coerce result of "
00460 + ::
to_string(
typeid( *
this )) +
" to EString" );
00461 }
00462
00464 virtual bool isImpl( EvalAs<EString> )
const {
return false; }
00465
00469 virtual string
evalImpl( EvalAs<string>,
const EvalContext& ctxt )
00470
throw( EvalException )
00471 {
00472
return( ::to_string( eval<EString>( ctxt )));
00473 }
00474
00477 virtual bool isImpl( EvalAs<string> )
const {
return is<EString>(); }
00478
00479
00481 virtual Timestamp
evalImpl( EvalAs<Timestamp>,
const EvalContext& )
00482 throw( EvalException )
00483 {
00484
throw EvalException(
"Cannot coerce result of "
00485 + ::
to_string(
typeid( *
this )) +
" to Timestamp" );
00486 }
00487
00489 virtual bool isImpl( EvalAs<Timestamp> )
const {
return(
false ); }
00490
00491
00492
00493 virtual void dump_children( string& s,
unsigned int indent )
const {}
00494 virtual string
value()
const {
return string(); }
00495
00496
00497
00498
00499
00500
private:
00501 DataType _type;
00502 };
00503
00504
00505
template<
typename T>
class TypedExpression;
00506
00511
template<>
00512 class TypedExpression<bool> :
public Expression
00513 {
00514
public:
00515 TypedExpression() :
Expression( DataType::BOOL ) {}
00516
00517
virtual bool evalImpl( EvalAs<bool>,
const EvalContext &ctxt )
00518
throw( EvalException ) = 0;
00519
00520 bool isImpl( EvalAs<bool> )
const {
return true; }
00521
00522
00523 int32
evalImpl( EvalAs<int32>,
const EvalContext &ctxt)
00524
throw( EvalException ) {
return eval<bool>(ctxt); }
00525
00526 bool isImpl( EvalAs<int32> )
const {
return true; }
00527
00528
00529 int64
evalImpl( EvalAs<int64>,
const EvalContext &ctxt)
00530
throw( EvalException ) {
return eval<bool>(ctxt); }
00531
00532 bool isImpl( EvalAs<int64> )
const {
return true; }
00533
00534
00535 single
evalImpl( EvalAs<single>,
const EvalContext &ctxt )
00536
throw( EvalException ) {
return eval<bool>(ctxt); }
00537
00538 bool isImpl( EvalAs<single> )
const {
return true; }
00539
00540
00541 double evalImpl( EvalAs<double>,
const EvalContext &ctxt )
00542
throw( EvalException ) {
return eval<bool>(ctxt); }
00543
00544 bool isImpl( EvalAs<double> )
const {
return true; }
00545
00546
00547 EString
evalImpl( EvalAs<EString>,
const EvalContext &ctxt )
00548
throw( EvalException )
00549 {
00550
return(
EString::coerce( eval<bool>(ctxt), ctxt.getPool() ));
00551 }
00552
00553 bool isImpl( EvalAs<EString> )
const {
return true; }
00554
00555
00556
00557
00558
00559
00560 };
00561
00562
00567
template<>
00568 class TypedExpression<int32> :
public Expression
00569 {
00570
public:
00571 TypedExpression() :
Expression( DataType::INT ) {}
00572
00573
virtual int32
evalImpl( EvalAs<int32>,
const EvalContext &ctxt )
00574
throw( EvalException ) = 0;
00575
00576 bool isImpl( EvalAs<int32> )
const {
return(
true ); }
00577
00578
00579 int64
evalImpl( EvalAs<int64>,
const EvalContext &ctxt )
00580
throw( EvalException ) {
return eval<int32>(ctxt); }
00581
00582 bool isImpl( EvalAs<int64> )
const {
return(
true ); }
00583
00584
00585 single
evalImpl( EvalAs<single>,
const EvalContext &ctxt )
00586
throw( EvalException ) {
return eval<int32>(ctxt); }
00587
00588 bool isImpl( EvalAs<single> )
const {
return(
true ); }
00589
00590
00591 double evalImpl( EvalAs<double>,
const EvalContext &ctxt )
00592
throw( EvalException ) {
return eval<int32>(ctxt); }
00593
00594 bool isImpl( EvalAs<double> )
const {
return(
true ); }
00595
00596
00597 EString
evalImpl( EvalAs<EString>,
const EvalContext &ctxt )
00598
throw( EvalException )
00599 {
00600
return(
EString::coerce( eval<int32>(ctxt), ctxt.getPool() ));
00601 }
00602
00603 bool isImpl(EvalAs<EString>)
const {
return(
true ); }
00604
00605
00606
00607
00608
00609 };
00610
00611
00616
template<>
00617 class TypedExpression<int64> :
public Expression
00618 {
00619
public:
00620 TypedExpression() :
Expression( DataType::LONG ) {}
00621
00622
virtual int64
evalImpl( EvalAs<int64>,
const EvalContext &ctxt )
00623
throw( EvalException ) = 0;
00624
00625 bool isImpl( EvalAs<int64> )
const {
return(
true ); }
00626
00627
00628 int32
evalImpl( EvalAs<int32>,
const EvalContext &ctxt )
00629
throw( EvalException ) {
return eval<int64>(ctxt); }
00630
00631 bool isImpl( EvalAs<int32> )
const {
return(
true ); }
00632
00633
00634 single
evalImpl( EvalAs<single>,
const EvalContext &ctxt )
00635
throw( EvalException ) {
return eval<int64>(ctxt); }
00636
00637 bool isImpl( EvalAs<single> )
const {
return(
true ); }
00638
00639
00640 double evalImpl( EvalAs<double>,
const EvalContext &ctxt )
00641
throw( EvalException ) {
return eval<int64>(ctxt); }
00642
00643 bool isImpl( EvalAs<double> )
const {
return(
true ); }
00644
00645
00646 EString
evalImpl( EvalAs<EString>,
const EvalContext &ctxt )
00647
throw( EvalException )
00648 {
00649
return(
EString::coerce( eval<int64>(ctxt), ctxt.getPool() ));
00650 }
00651
00652 bool isImpl(EvalAs<EString>)
const {
return(
true ); }
00653
00654
00655
00656
00657 };
00658
00659
00660
00665
template<>
00666 class TypedExpression<single> :
public Expression
00667 {
00668
public:
00669 TypedExpression() :
Expression( DataType::SINGLE ) {}
00670
00671
virtual single
evalImpl( EvalAs<single>,
const EvalContext &ctxt )
00672
throw( EvalException ) = 0;
00673
00674 bool isImpl( EvalAs<single> )
const {
return(
true ); }
00675
00676 EString
evalImpl( EvalAs<EString>,
const EvalContext &ctxt )
00677
throw( EvalException )
00678 {
00679
return(
EString::coerce( eval<single>(ctxt), ctxt.getPool() ));
00680 }
00681
00682 bool isImpl(EvalAs<EString>)
const {
return(
true ); }
00683
00684
00685
00686
00687 };
00688
00689
00694
template<>
00695 class TypedExpression<double> :
public Expression
00696 {
00697
public:
00698 TypedExpression() :
Expression( DataType::DOUBLE ) {}
00699
00700
virtual double evalImpl( EvalAs<double>,
const EvalContext &ctxt )
00701
throw( EvalException ) = 0;
00702
00703 bool isImpl( EvalAs<double> )
const {
return(
true ); }
00704
00705 EString
evalImpl( EvalAs<EString>,
const EvalContext &ctxt )
00706
throw( EvalException )
00707 {
00708
return(
EString::coerce(eval<double>(ctxt), ctxt.getPool() ));
00709 }
00710
00711 bool isImpl(EvalAs<EString>)
const {
return(
true ); }
00712
00713
00714
00715
00716 };
00717
00718
00719
00724
template<>
00725 class TypedExpression<EString> :
public Expression
00726 {
00727
public:
00728
virtual EString
evalImpl( EvalAs<EString>,
const EvalContext &ctxt )
00729
throw( EvalException ) = 0;
00730
00731 bool isImpl( EvalAs<EString> )
const {
return(
true ); }
00732
00733 TypedExpression() :
Expression( DataType::STRING ) {}
00734 };
00735
00740
template<>
00741 class TypedExpression<Timestamp> :
public Expression
00742 {
00743
public:
00744 TypedExpression() :
Expression ( DataType::TIMESTAMP ) {}
00745
00746
virtual Timestamp
evalImpl( EvalAs<Timestamp>,
const EvalContext &ctxt)
00747
throw( EvalException ) = 0;
00748
00749 bool isImpl( EvalAs<Timestamp> )
const {
return true; }
00750 };
00751
00752
BOREALIS_NAMESPACE_END
00753
#endif // EXPRESSION_H