summaryrefslogtreecommitdiffstats
path: root/qlparser/qtnode.cc
diff options
context:
space:
mode:
Diffstat (limited to 'qlparser/qtnode.cc')
-rw-r--r--qlparser/qtnode.cc645
1 files changed, 645 insertions, 0 deletions
diff --git a/qlparser/qtnode.cc b/qlparser/qtnode.cc
new file mode 100644
index 0000000..77313db
--- /dev/null
+++ b/qlparser/qtnode.cc
@@ -0,0 +1,645 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ *
+ * PURPOSE:
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, QtNode: $Id: qtnode.cc,v 1.27 2002/06/05 18:18:17 coman Exp $";
+
+#include "qlparser/qtnode.hh"
+#include "catalogmgr/typefactory.hh"
+#include "relcatalogif/type.hh"
+#include "relcatalogif/basetype.hh"
+
+#include <iostream>
+#include <algorithm>
+
+
+const QtNode::QtNodeType QtNode::nodeType = QT_UNDEFINED_NODE;
+
+ const int QtNode::QtNodes = 80;
+
+ const QtNode::QtNodeType QtNode::QtRoot = QT_UNDEFINED_NODE;
+
+ const QtNode::QtNodeType QtNode::QtInheritance[][2] = {
+ {QT_UNDEFINED_NODE, QT_EXECUTE},
+ {QT_EXECUTE, QT_COMMAND},
+ {QT_EXECUTE, QT_DELETE},
+ {QT_EXECUTE, QT_INSERT},
+ {QT_EXECUTE, QT_PYRAMID},
+ {QT_EXECUTE, QT_UPDATE},
+ {QT_UNDEFINED_NODE, QT_ONC_STREAM},
+ {QT_ONC_STREAM, QT_ITERATOR},
+ {QT_ITERATOR, QT_JOIN_ITERATOR},
+ {QT_ITERATOR, QT_OPERATION_ITERATOR},
+ {QT_ITERATOR, QT_SELECTION_ITERATOR},
+ {QT_ONC_STREAM, QT_MDD_ACCESS},
+ {QT_UNDEFINED_NODE, QT_OPERATION},
+ {QT_OPERATION, QT_BINARY_OPERATION},
+ {QT_BINARY_OPERATION, QT_BINARY_INDUCE},
+ {QT_BINARY_INDUCE, QT_AND},
+ {QT_BINARY_INDUCE, QT_BIT},
+ {QT_BINARY_INDUCE, QT_DIV},
+ {QT_BINARY_INDUCE, QT_EQUAL},
+ {QT_BINARY_INDUCE, QT_IS},
+ {QT_BINARY_INDUCE, QT_LESS},
+ {QT_BINARY_INDUCE, QT_LESS_EQUAL},
+ {QT_BINARY_INDUCE, QT_MINUS},
+ {QT_BINARY_INDUCE, QT_MULT},
+ {QT_BINARY_INDUCE, QT_NOT_EQUAL},
+ {QT_BINARY_INDUCE, QT_OR},
+ {QT_BINARY_INDUCE, QT_OVERLAY},
+ {QT_BINARY_INDUCE, QT_PLUS},
+ {QT_BINARY_INDUCE, QT_XOR},
+ {QT_BINARY_OPERATION, QT_CONDENSEOP},
+ {QT_BINARY_OPERATION, QT_EXTEND},
+ {QT_BINARY_OPERATION, QT_INTERVALOP},
+ {QT_BINARY_OPERATION, QT_MARRAYOP},
+ {QT_BINARY_OPERATION, QT_SCALE},
+ {QT_BINARY_OPERATION, QT_SHIFT},
+ {QT_OPERATION, QT_CONST},
+ {QT_OPERATION, QT_GROUP_ITERATOR},
+ {QT_OPERATION, QT_IDENT},
+ {QT_OPERATION, QT_MDD_STREAM},
+ {QT_OPERATION, QT_NARY_OPERATION},
+ {QT_NARY_OPERATION, QT_MINTERVALOP},
+ {QT_NARY_OPERATION, QT_POINTOP},
+ {QT_OPERATION, QT_UNARY_OPERATION},
+ {QT_UNARY_OPERATION, QT_CONDENSE},
+ {QT_CONDENSE, QT_ADDCELLS},
+ {QT_CONDENSE, QT_ALL},
+ {QT_CONDENSE, QT_AVGCELLS},
+ {QT_CONDENSE, QT_COUNTCELLS},
+ {QT_CONDENSE, QT_MAXCELLS},
+ {QT_CONDENSE, QT_MINCELLS},
+ {QT_CONDENSE, QT_SOME},
+ {QT_UNARY_OPERATION, QT_CONVERSION},
+ {QT_UNARY_OPERATION, QT_CSE_ROOT},
+ {QT_UNARY_OPERATION, QT_DOMAIN_OPERATION},
+ {QT_UNARY_OPERATION, QT_HI},
+ {QT_UNARY_OPERATION, QT_LO},
+ {QT_UNARY_OPERATION, QT_OID},
+ {QT_UNARY_OPERATION, QT_SDOM},
+ {QT_UNARY_OPERATION, QT_UNARY_INDUCE},
+ {QT_UNARY_INDUCE, QT_CAST},
+ {QT_UNARY_INDUCE, QT_DOT},
+ {QT_UNARY_INDUCE, QT_IMAGINARPART},
+ {QT_UNARY_INDUCE, QT_NOT},
+ {QT_UNARY_INDUCE, QT_REALPART},
+ {QT_UNARY_INDUCE, QT_ABS},
+ {QT_UNARY_INDUCE, QT_SQRT},
+ {QT_UNARY_INDUCE, QT_EXP},
+ {QT_UNARY_INDUCE, QT_LOG},
+ {QT_UNARY_INDUCE, QT_LN},
+ {QT_UNARY_INDUCE, QT_SIN},
+ {QT_UNARY_INDUCE, QT_COS},
+ {QT_UNARY_INDUCE, QT_TAN},
+ {QT_UNARY_INDUCE, QT_SINH},
+ {QT_UNARY_INDUCE, QT_COSH},
+ {QT_UNARY_INDUCE, QT_TANH},
+ {QT_UNARY_INDUCE, QT_ARCSIN},
+ {QT_UNARY_INDUCE, QT_ARCCOS},
+ {QT_UNARY_INDUCE, QT_ARCTAN},
+ {QT_OPERATION, QT_MDD_VAR}
+};
+
+
+
+int QtNode::minim[QtNodes];
+int QtNode::maxim[QtNodes];
+int QtNode::child_range[QtNodes+1];
+
+bool QtNode::MinMaxDone = false;
+
+QtNode::QtNode()
+ : parent(NULL)
+{
+ if (!MinMaxDone) {
+ MinMaxDone = true;
+ SetMinMax();
+ }
+}
+
+
+QtNode::QtNode( QtNode* node )
+ : parent( node )
+{
+ if (!MinMaxDone) {
+ MinMaxDone = true;
+ SetMinMax();
+ }
+}
+
+
+QtNode::~QtNode()
+{
+}
+
+bool
+QtNode::subtype( enum QtNodeType a, enum QtNodeType b )
+{
+ return (minim[a]<=minim[b] && maxim[b]<=maxim[a]);
+}
+
+
+QtNode::QtNodeList*
+QtNode::getChilds( QtChildType flag )
+{
+ RMDBCLASS( "QtNode", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
+
+ // Default definition is used for all leaf nodes.
+
+ // Algorithm:
+ //
+ // In mode QT_ALL_NODES each node calls getChild() of every son,
+ // merges these lists and inserts direct childs but not the node
+ // itself.
+ // In mode QT_DIRECT_CHILDS each node inserts just direct childs.
+ // In mode QT_LEAF_NODES the method call is passed to the sons
+ // and just the leaf nodes insert themselves.
+
+ QtNodeList* resultList=NULL;
+
+ resultList = new QtNodeList();
+
+ if( flag == QT_LEAF_NODES )
+ resultList->push_back( this );
+
+ return resultList;
+}
+
+
+QtNode::QtNodeList*
+QtNode::getChild( const QtNodeType node, QtChildType flag )
+{
+ RMDBCLASS( "QtNode", "getChild( QtChildType )", "qlparser", __FILE__, __LINE__ )
+
+ QtNodeList* resultList=NULL;
+ QtNodeList::iterator iter;
+
+ resultList = getChilds( flag );
+
+ for( iter=resultList->begin(); iter!=resultList->end(); iter++ )
+ if( node != (*iter)->getNodeType() )
+ resultList->erase( iter-- );
+
+ return resultList;
+}
+
+
+bool
+QtNode::equalMeaning( QtNode* /*node*/ )
+{
+ return false;
+}
+
+
+std::string
+QtNode::getSpelling()
+{
+ return "";
+}
+
+QtNode::QtAreaType
+QtNode::getAreaType()
+{
+ return QT_AREA_SCALAR;
+}
+
+
+
+void
+QtNode::simplify()
+{
+ RMDBCLASS( "QtNode", "simplify()", "qlparser", __FILE__, __LINE__ )
+
+ // Default method for all classes that have no implementation.
+ // Method is used bottom up.
+
+ QtNodeList* resultList=NULL;
+ QtNodeList::iterator iter;
+
+ try
+ {
+ resultList = getChilds( QT_DIRECT_CHILDS );
+ for( iter=resultList->begin(); iter!=resultList->end(); iter++ )
+ (*iter)->simplify();
+ }
+ catch(...)
+ {
+ if( resultList )
+ {
+ delete resultList;
+ resultList=NULL;
+ }
+ throw;
+ }
+
+ delete resultList;
+ resultList=NULL;
+}
+
+
+/*
+void
+QtNode::rewriteOps()
+{
+ RMDBGONCE( 1, RMDebug::module_qlparser, "QtNode", " QtNode::rewriteOps() " )
+
+ // Default method for all classes that have no implementation.
+ // Method is used top down.
+
+ QtNodeList* resultList=NULL;
+ QtNodeList::iterator iter;
+
+ resultList = getChilds( QT_DIRECT_CHILDS );
+ for( iter=resultList->begin(); iter!=resultList->end(); iter++ )
+ (*iter)->rewriteOps();
+
+ delete resultList;
+ resultList=NULL;
+}
+*/
+
+/*
+void
+QtNode::sortAssociativeOps()
+{
+ RMDBGONCE( 1, RMDebug::module_qlparser, "QtScale", " QtNode::sortAssociativeOps()" )
+
+ // Default method for all nodes that have no own method
+ // method is used top down
+
+ QtNodeList* resultList=NULL;
+ QtNodeList::iterator iter;
+
+ resultList = getChilds( QT_DIRECT_CHILDS );
+
+ for( iter=resultList->begin(); iter!=resultList->end(); iter++ )
+ (*iter)->sortAssociativeOps();
+
+ delete resultList;
+ resultList=NULL;
+}
+*/
+
+
+/*
+void
+QtNode::checkIdempotency()
+{
+ RMDBGONCE( 1, RMDebug::module_qlparser, "QtNode", " QtNode::checkIdempotency()" )
+
+ // method is used bottom up
+ // default method for all nodes that have no own method
+}
+*/
+
+QtNode::QtNodeType
+QtNode::getQtNodeTypeParent (QtNode::QtNodeType node) {
+ int i = 0;
+ for (i=0; i<QtNodes; i++)
+ if ( QtInheritance[i][1] == node ) return QtInheritance[i][0];
+ throw r_Error(QTNODETYPEPARENTDOESNOTEXIST);
+}
+
+
+bool
+operator<(const QtNode::QtNodePair a, const QtNode::QtNodePair b){
+ return (a.base < b.base);
+}
+
+void
+QtNode::num_node (const QtNodePair *arr, const enum QtNodeType x) {
+ int i;
+ static int ID = 0 ;
+ enum QtNodeType child;
+ minim[x] = ID++;
+ for (i = child_range[x]; i < child_range[x+1]; i++)
+ num_node(arr, arr[i].deriv);
+ maxim[x] = ID++;
+}
+
+void
+QtNode::set_child_range(const QtNodePair *arr) {
+ int i;
+ child_range[QtNodes] = QtNodes-1;
+ for (i=QtNodes-3; i>=0; i--)
+ if (arr[i].base != arr[i+1].base) child_range[arr[i+1].base] = i+1;
+ child_range[arr[0].base] = 0;
+ for (i=QtNodes-1; i>0; i--)
+ if (child_range[i] == 0) child_range[i] = child_range[i+1];
+}
+
+void
+QtNode::SetMinMax()
+{
+ int i;
+ QtNodePair arr[QtNodes-1];
+ for (i=0; i<(QtNodes-1); i++) {
+ arr[i].base = QtInheritance[i][0];
+ arr[i].deriv = QtInheritance[i][1];
+ }
+ std::sort(arr,arr+QtNodes-1);
+ //creating child_range
+ set_child_range(arr);
+ //numbering the nodes
+ num_node(arr, QtRoot);
+}
+
+
+QtTypeElement::QtTypeElement()
+ : dataType( QT_TYPE_UNKNOWN ),
+ type(NULL),
+ name(NULL)
+{
+}
+
+
+
+QtTypeElement::QtTypeElement( const QtDataType initDataType,
+ const char* initName )
+ : dataType( QT_TYPE_UNKNOWN ),
+ type( NULL ),
+ name( NULL )
+{
+ setDataType( initDataType );
+
+ if( initName ) name = strdup( initName );
+}
+
+
+
+QtTypeElement::QtTypeElement( const Type* initType,
+ const char* initName )
+ : dataType( QT_TYPE_UNKNOWN ),
+ type( NULL ),
+ name( NULL )
+{
+ setType( initType );
+
+ if( initName ) name = strdup( initName );
+}
+
+
+
+QtTypeElement::QtTypeElement( const QtTypeElement& typeElement )
+ : dataType( typeElement.dataType ),
+ type( typeElement.type ),
+ name(NULL)
+{
+ if( typeElement.name ) name = strdup( typeElement.name );
+}
+
+
+
+QtTypeElement::~QtTypeElement()
+{
+ // Note: Types are free by the type factory.
+
+ if( name )
+ {
+ free( name );
+ name=NULL;
+ }
+}
+
+
+
+const QtTypeElement&
+QtTypeElement::operator=( const QtTypeElement& obj )
+{
+ if( this != &obj )
+ {
+ if( name )
+ {
+ free( name );
+ name = NULL;
+ }
+
+ dataType = obj.dataType;
+ type = obj.type;
+
+ if( obj.name ) name = strdup( obj.name );
+
+ }
+
+ return *this;
+}
+
+
+
+void
+QtTypeElement::printStatus( std::ostream& s ) const
+{
+ if( type )
+ {
+ char* typeStructure = type->getTypeStructure();
+ s << typeStructure << std::flush;
+ free( typeStructure );
+ typeStructure=NULL;
+ }
+ else
+ {
+ switch( dataType )
+ {
+ case QT_STRING:
+ s << "string" << std::flush;
+ break;
+
+ case QT_INTERVAL:
+ s << "interval" << std::flush;
+ break;
+
+ case QT_MINTERVAL:
+ s << "minterval" << std::flush;
+ break;
+
+ case QT_POINT:
+ s << "point" << std::flush;
+ break;
+
+ default:
+ // including case QT_TYPE_UNKNOWN
+ s << "<unknown type>" << std::flush;
+ break;
+ }
+ }
+
+ if( name )
+ s << ":" << name << std::flush;
+}
+
+
+
+void
+QtTypeElement::setDataType( const QtDataType newDataType )
+{
+ dataType = newDataType;
+
+ // reset type information
+ type = NULL;
+
+ switch( dataType )
+ {
+ case QT_TYPE_UNKNOWN:
+ break;
+ case QT_BOOL:
+ type = TypeFactory::mapType("Bool");
+ break;
+ case QT_CHAR:
+ type = TypeFactory::mapType("Char");
+ break;
+ case QT_OCTET:
+ type = TypeFactory::mapType("Octet");
+ break;
+ case QT_USHORT:
+ type = TypeFactory::mapType("UShort");
+ break;
+ case QT_SHORT:
+ type = TypeFactory::mapType("Short");
+ break;
+ case QT_ULONG:
+ type = TypeFactory::mapType("ULong");
+ break;
+ case QT_LONG:
+ type = TypeFactory::mapType("Long");
+ break;
+ case QT_FLOAT:
+ type = TypeFactory::mapType("Float");
+ break;
+ case QT_DOUBLE:
+ type = TypeFactory::mapType("Double");
+ break;
+ case QT_COMPLEXTYPE1:
+ type = TypeFactory::mapType("Complex1");
+ break;
+ case QT_COMPLEXTYPE2:
+ type = TypeFactory::mapType("Complex2");
+ break;
+
+ case QT_MDD:
+ case QT_COMPLEX:
+ RMInit::logOut << "QtTypeElement::setDataType() - MDD and complex types need to be specified further." << std::endl;
+ break;
+
+ case QT_STRING:
+ case QT_INTERVAL:
+ case QT_MINTERVAL:
+ case QT_POINT:
+ default:
+ // transient types
+ break;
+ }
+}
+
+
+
+void
+QtTypeElement::setType(const Type* newType )
+{
+ type = NULL;
+ dataType = QT_TYPE_UNKNOWN;
+
+ if( newType )
+ switch( newType->getType() )
+ {
+ case BOOLTYPE: dataType = QT_BOOL; break;
+ case CHAR: dataType = QT_CHAR; break;
+ case OCTET: dataType = QT_OCTET; break;
+ case USHORT: dataType = QT_USHORT; break;
+ case SHORT: dataType = QT_SHORT; break;
+ case ULONG: dataType = QT_ULONG; break;
+ case LONG: dataType = QT_LONG; break;
+ case FLOAT: dataType = QT_FLOAT; break;
+ case DOUBLE: dataType = QT_DOUBLE; break;
+ case COMPLEXTYPE1: dataType = QT_COMPLEXTYPE1; break;
+ case COMPLEXTYPE2: dataType = QT_COMPLEXTYPE2; break;
+ case MDDTYPE: dataType = QT_MDD; break;
+ case STRUCT: dataType = QT_COMPLEX; break;
+ default: dataType = QT_TYPE_UNKNOWN; break;
+ }
+
+ // if type is supported
+ if( dataType != QT_TYPE_UNKNOWN )
+ type = newType;
+}
+
+
+
+QtTypeTuple::QtTypeTuple( unsigned int length )
+ : tuple( length )
+{
+}
+
+
+
+void
+QtTypeTuple::concat( const QtTypeTuple& typeTuple )
+{
+ // reserve space for concatenated type
+ tuple.reserve( tuple.size() + typeTuple.tuple.size() );
+
+ // concatenate tuples
+ for( std::vector<QtTypeElement>::const_iterator iter = typeTuple.tuple.begin();
+ iter != typeTuple.tuple.end(); iter++ )
+ tuple.push_back( *iter );
+}
+
+
+
+void
+QtTypeTuple::concat( const QtTypeElement& typeElement )
+{
+ tuple.push_back( typeElement );
+}
+
+
+
+void
+QtTypeTuple::printStatus( std::ostream& s ) const
+{
+ s << "<" << std::flush;
+
+ for( std::vector<QtTypeElement>::const_iterator iter = tuple.begin();
+ iter != tuple.end();
+ iter++ )
+ {
+ if( iter != tuple.begin() )
+ s << ", " << std::flush;
+
+ (*iter).printStatus( s );
+ }
+
+ s << ">" << std::flush;
+}
+
+
+
+