summaryrefslogtreecommitdiffstats
path: root/qlparser
diff options
context:
space:
mode:
authorConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
committerConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
commit8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 (patch)
treebd328a4dd4f92d32202241b5e3a7f36177792c5f /qlparser
downloadrasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip
Initial commitv8.0
Diffstat (limited to 'qlparser')
-rw-r--r--qlparser/Makefile.am93
-rw-r--r--qlparser/alloca.c531
-rw-r--r--qlparser/autogen_qtui.cc1151
-rw-r--r--qlparser/autogen_qtui.hh296
-rw-r--r--qlparser/autogen_qtui.icc44
-rw-r--r--qlparser/lex.ll354
-rw-r--r--qlparser/oql.yy2185
-rw-r--r--qlparser/parseinfo.cc102
-rw-r--r--qlparser/parseinfo.hh111
-rw-r--r--qlparser/parseinfo.icc100
-rw-r--r--qlparser/qtatomicdata.cc212
-rw-r--r--qlparser/qtatomicdata.hh134
-rw-r--r--qlparser/qtatomicdata.icc29
-rw-r--r--qlparser/qtbinaryfunc.cc1174
-rw-r--r--qlparser/qtbinaryfunc.hh201
-rw-r--r--qlparser/qtbinaryfunc.icc47
-rw-r--r--qlparser/qtbinaryinduce.cc959
-rw-r--r--qlparser/qtbinaryinduce.hh261
-rw-r--r--qlparser/qtbinaryinduce.icc56
-rw-r--r--qlparser/qtbinaryinduce2.cc919
-rw-r--r--qlparser/qtbinaryinduce2.hh358
-rw-r--r--qlparser/qtbinaryinduce2.icc95
-rw-r--r--qlparser/qtbinaryoperation.cc432
-rw-r--r--qlparser/qtbinaryoperation.hh150
-rw-r--r--qlparser/qtbinaryoperation.icc89
-rw-r--r--qlparser/qtcommand.cc182
-rw-r--r--qlparser/qtcommand.hh97
-rw-r--r--qlparser/qtcommand.icc35
-rw-r--r--qlparser/qtcomplexdata.cc109
-rw-r--r--qlparser/qtcomplexdata.hh92
-rw-r--r--qlparser/qtcomplexdata.icc29
-rw-r--r--qlparser/qtcondense.cc801
-rw-r--r--qlparser/qtcondense.hh352
-rw-r--r--qlparser/qtcondense.icc197
-rw-r--r--qlparser/qtcondenseop.cc440
-rw-r--r--qlparser/qtcondenseop.hh131
-rw-r--r--qlparser/qtcondenseop.icc44
-rw-r--r--qlparser/qtconst.cc265
-rw-r--r--qlparser/qtconst.hh117
-rw-r--r--qlparser/qtconst.icc43
-rw-r--r--qlparser/qtconversion.cc590
-rw-r--r--qlparser/qtconversion.hh113
-rw-r--r--qlparser/qtconversion.icc35
-rw-r--r--qlparser/qtdata.cc127
-rw-r--r--qlparser/qtdata.hh200
-rw-r--r--qlparser/qtdata.icc137
-rw-r--r--qlparser/qtdelete.cc268
-rw-r--r--qlparser/qtdelete.hh100
-rw-r--r--qlparser/qtdelete.icc35
-rw-r--r--qlparser/qtdomainoperation.cc950
-rw-r--r--qlparser/qtdomainoperation.hh124
-rw-r--r--qlparser/qtdomainoperation.icc66
-rw-r--r--qlparser/qtexecute.hh66
-rw-r--r--qlparser/qtinsert.cc361
-rw-r--r--qlparser/qtinsert.hh104
-rw-r--r--qlparser/qtinsert.icc49
-rw-r--r--qlparser/qtintervaldata.cc128
-rw-r--r--qlparser/qtintervaldata.hh102
-rw-r--r--qlparser/qtintervaldata.icc42
-rw-r--r--qlparser/qtintervalop.cc311
-rw-r--r--qlparser/qtintervalop.hh84
-rw-r--r--qlparser/qtintervalop.icc34
-rw-r--r--qlparser/qtiterator.cc260
-rw-r--r--qlparser/qtiterator.hh118
-rw-r--r--qlparser/qtiterator.icc36
-rw-r--r--qlparser/qtjoiniterator.cc338
-rw-r--r--qlparser/qtjoiniterator.hh120
-rw-r--r--qlparser/qtjoiniterator.icc35
-rw-r--r--qlparser/qtmarrayop.cc314
-rw-r--r--qlparser/qtmarrayop.hh90
-rw-r--r--qlparser/qtmarrayop.icc34
-rw-r--r--qlparser/qtmarrayop2.cc369
-rw-r--r--qlparser/qtmarrayop2.hh113
-rw-r--r--qlparser/qtmarrayop2.icc54
-rw-r--r--qlparser/qtmdd.cc329
-rw-r--r--qlparser/qtmdd.hh138
-rw-r--r--qlparser/qtmdd.icc59
-rw-r--r--qlparser/qtmddaccess.cc250
-rw-r--r--qlparser/qtmddaccess.hh114
-rw-r--r--qlparser/qtmddaccess.icc42
-rw-r--r--qlparser/qtmintervaldata.cc188
-rw-r--r--qlparser/qtmintervaldata.hh108
-rw-r--r--qlparser/qtmintervaldata.icc59
-rw-r--r--qlparser/qtmintervalop.cc222
-rw-r--r--qlparser/qtmintervalop.hh81
-rw-r--r--qlparser/qtmintervalop.icc34
-rw-r--r--qlparser/qtnaryoperation.cc414
-rw-r--r--qlparser/qtnaryoperation.hh137
-rw-r--r--qlparser/qtnaryoperation.icc50
-rw-r--r--qlparser/qtnode.cc645
-rw-r--r--qlparser/qtnode.hh503
-rw-r--r--qlparser/qtnode.icc130
-rw-r--r--qlparser/qtoid.cc179
-rw-r--r--qlparser/qtoid.hh78
-rw-r--r--qlparser/qtoid.icc35
-rw-r--r--qlparser/qtoncstream.cc49
-rw-r--r--qlparser/qtoncstream.hh102
-rw-r--r--qlparser/qtoncstream.icc42
-rw-r--r--qlparser/qtoperation.cc126
-rw-r--r--qlparser/qtoperation.hh120
-rw-r--r--qlparser/qtoperation.icc43
-rw-r--r--qlparser/qtoperationiterator.cc303
-rw-r--r--qlparser/qtoperationiterator.hh120
-rw-r--r--qlparser/qtoperationiterator.icc74
-rw-r--r--qlparser/qtpointdata.cc114
-rw-r--r--qlparser/qtpointdata.hh101
-rw-r--r--qlparser/qtpointdata.icc45
-rw-r--r--qlparser/qtpointop.cc214
-rw-r--r--qlparser/qtpointop.hh81
-rw-r--r--qlparser/qtpointop.icc34
-rw-r--r--qlparser/qtscalardata.cc204
-rw-r--r--qlparser/qtscalardata.hh137
-rw-r--r--qlparser/qtscalardata.icc58
-rw-r--r--qlparser/qtselectioniterator.cc281
-rw-r--r--qlparser/qtselectioniterator.hh119
-rw-r--r--qlparser/qtselectioniterator.icc68
-rw-r--r--qlparser/qtstringdata.cc88
-rw-r--r--qlparser/qtstringdata.hh97
-rw-r--r--qlparser/qtstringdata.icc42
-rw-r--r--qlparser/qtunaryfunc.cc414
-rw-r--r--qlparser/qtunaryfunc.hh161
-rw-r--r--qlparser/qtunaryfunc.icc51
-rw-r--r--qlparser/qtunaryinduce.cc1013
-rw-r--r--qlparser/qtunaryinduce.hh267
-rw-r--r--qlparser/qtunaryinduce.icc84
-rw-r--r--qlparser/qtunaryoperation.cc204
-rw-r--r--qlparser/qtunaryoperation.hh111
-rw-r--r--qlparser/qtunaryoperation.icc59
-rw-r--r--qlparser/qtupdate.cc812
-rw-r--r--qlparser/qtupdate.hh119
-rw-r--r--qlparser/qtupdate.icc65
-rw-r--r--qlparser/qtvariable.cc392
-rw-r--r--qlparser/qtvariable.hh136
-rw-r--r--qlparser/qtvariable.icc84
-rw-r--r--qlparser/querytree.cc489
-rw-r--r--qlparser/querytree.hh265
-rw-r--r--qlparser/querytree.icc47
-rw-r--r--qlparser/rasml.awk9
-rw-r--r--qlparser/rasmlgrammar.html27
-rw-r--r--qlparser/symtab.cc159
-rw-r--r--qlparser/symtab.hh110
-rw-r--r--qlparser/test/Makefile89
-rw-r--r--qlparser/test/insertbin.cpp316
-rw-r--r--qlparser/test/template_inst.hh152
-rw-r--r--qlparser/test/test_evaluate.cc338
-rw-r--r--qlparser/test/test_qlparser.cc205
146 files changed, 31559 insertions, 0 deletions
diff --git a/qlparser/Makefile.am b/qlparser/Makefile.am
new file mode 100644
index 0000000..7638cea
--- /dev/null
+++ b/qlparser/Makefile.am
@@ -0,0 +1,93 @@
+# -*-Makefile-*- (for Emacs)
+#
+# 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>.
+#
+# MAKEFILE FOR:
+# module qlparser
+#
+#
+# COMMENTS:
+#
+#
+##################################################################
+
+noinst_LIBRARIES=libqlparser.a
+
+# -I gnererates an interactive scanner which doesn't try to look ahead past a newline
+# -i generates a scanner which doesn't care about upper and lower case; doesn't work
+AM_LFLAGS=-i -I
+
+YACC = bison
+# -d generates token definitions in .h file
+AM_YFLAGS=-d -y
+AM_CXXFLAGS=@BASEDBCXXFLAGS@
+AM_CFLAGS=$(CXXFLAGS)
+libqlparser_a_SOURCES=oql.yy lex.ll alloca.c\
+ symtab.cc symtab.hh \
+ qtoncstream.cc qtoncstream.hh qtoncstream.icc \
+ qtmddaccess.cc qtmddaccess.hh qtmddaccess.icc \
+ qtiterator.cc qtiterator.hh qtiterator.icc \
+ qtoperationiterator.cc qtoperationiterator.hh qtoperationiterator.icc \
+ qtselectioniterator.cc qtselectioniterator.hh qtselectioniterator.icc \
+ qtjoiniterator.cc qtjoiniterator.hh qtjoiniterator.icc \
+ qtoperation.cc qtoperation.hh qtoperation.icc \
+ qtbinaryoperation.cc qtbinaryoperation.hh qtbinaryoperation.icc \
+ qtbinaryinduce.cc qtbinaryinduce.hh qtbinaryinduce.icc \
+ qtbinaryinduce2.cc qtbinaryinduce2.hh qtbinaryinduce2.icc \
+ qtunaryoperation.cc qtunaryoperation.hh qtunaryoperation.icc \
+ qtunaryinduce.cc qtunaryinduce.hh qtunaryinduce.icc \
+ qtvariable.cc qtvariable.hh qtvariable.icc \
+ qtconst.cc qtconst.hh qtconst.icc \
+ qtdata.cc qtdata.hh qtdata.icc \
+ qtscalardata.cc qtscalardata.hh qtscalardata.icc \
+ qtatomicdata.cc qtatomicdata.hh qtatomicdata.icc \
+ qtcomplexdata.cc qtcomplexdata.hh qtcomplexdata.icc \
+ qtmdd.cc qtmdd.hh qtmdd.icc \
+ qtstringdata.cc qtstringdata.hh qtstringdata.icc \
+ qtcondense.cc qtcondense.hh qtcondense.icc \
+ parseinfo.cc parseinfo.hh parseinfo.icc \
+ qtdomainoperation.cc qtdomainoperation.hh qtdomainoperation.icc \
+ qtconversion.cc qtconversion.hh qtconversion.icc\
+ qtupdate.cc qtupdate.hh qtupdate.icc \
+ qtinsert.cc qtinsert.hh qtinsert.icc \
+ qtdelete.cc qtdelete.hh \
+ qtcommand.cc qtcommand.hh qtcommand.icc \
+ qtoid.cc qtoid.hh qtoid.icc\
+ qtintervalop.cc qtintervalop.hh qtintervalop.icc \
+ qtmintervalop.cc qtmintervalop.hh qtmintervalop.icc \
+ qtintervaldata.cc qtintervaldata.hh qtintervaldata.icc \
+ qtpointop.cc qtpointop.hh qtpointop.icc \
+ qtmintervaldata.cc qtmintervaldata.hh qtmintervaldata.icc \
+ qtpointdata.cc qtpointdata.hh qtpointdata.icc \
+ qtnaryoperation.cc qtnaryoperation.hh qtnaryoperation.icc \
+ qtunaryfunc.cc qtunaryfunc.hh qtunaryfunc.icc \
+ qtbinaryfunc.cc qtbinaryfunc.hh qtbinaryfunc.icc \
+ qtmarrayop.cc qtmarrayop.hh qtmarrayop.icc \
+ qtmarrayop2.cc qtmarrayop2.hh qtmarrayop2.icc \
+ qtcondenseop.cc qtcondenseop.hh qtcondenseop.icc \
+ qtnode.cc qtnode.hh qtnode.icc \
+ querytree.cc querytree.hh querytree.icc \
+ qtexecute.hh qtdelete.icc
+EXTRA_libqlparser_a_SOURCES = autogen_qtui.hh autogen_qtui.icc autogen_qtui.cc
+
+BUILT_SOURCES=lex.cc oql.cc oql.h
+CLEANFILES=lex.cc oql.cc oql.h
diff --git a/qlparser/alloca.c b/qlparser/alloca.c
new file mode 100644
index 0000000..d9a7ba2
--- /dev/null
+++ b/qlparser/alloca.c
@@ -0,0 +1,531 @@
+/*
+* 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>.
+*/
+#include "mymalloc/mymalloc.h"
+/* alloca.c -- allocate automatically reclaimed memory
+ (Mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+ J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+ There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef emacs
+#include "blockinput.h"
+#endif
+
+/* If compiling with GCC 2, this file's not needed. */
+#if !defined (__GNUC__) || __GNUC__ < 2
+#ifndef SOLARIS
+
+/* If someone has defined alloca as a macro,
+ there must be some other way alloca is supposed to work. */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+/* If your stack is a linked list of frames, you have to
+ provide an "address metric" ADDRESS_FUNCTION macro. */
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Different portions of Emacs need to call different versions of
+ malloc. The Emacs executable needs alloca to call xmalloc, because
+ ordinary malloc isn't protected from input signals. On the other
+ hand, the utilities in lib-src need alloca to call malloc; some of
+ them are very simple, and don't have an xmalloc routine.
+
+ Non-Emacs programs expect this to call use xmalloc.
+
+ Callers below should use malloc. */
+
+/*
+#ifndef emacs
+#define malloc xmalloc
+#endif
+*/
+extern pointer mymalloc ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* Direction unknown. */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
+
+#else /* STACK_DIRECTION == 0; need run-time code. */
+
+static int stack_dir; /* 1 or -1 once known. */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction ()
+{
+ static char *addr = NULL; /* Address of first `dummy', once known. */
+ auto char dummy; /* To get stack address. */
+
+ if (addr == NULL)
+ { /* Initial entry. */
+ addr = ADDRESS_FUNCTION (dummy);
+
+ find_stack_direction (); /* Recurse once. */
+ }
+ else
+ {
+ /* Second entry. */
+ if (ADDRESS_FUNCTION (dummy) > addr)
+ stack_dir = 1; /* Stack grew upward. */
+ else
+ stack_dir = -1; /* Stack grew downward. */
+ }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+ (a) chain together all alloca'ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc
+ alignment chunk size. The following default should work okay. */
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* To force sizeof(header). */
+ struct
+ {
+ union hdr *next; /* For chaining headers. */
+ char *deep; /* For stack depth measure. */
+ } h;
+} header;
+
+static header *last_alloca_header = NULL; /* -> last alloca header. */
+
+/* Return a pointer to at least SIZE bytes of storage,
+ which will be automatically reclaimed upon exit from
+ the procedure that called alloca. Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32. */
+
+pointer
+alloca (size)
+ unsigned size;
+{
+ auto char probe; /* Probes stack depth: */
+ register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* Unknown growth direction. */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca'd storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* Traverses linked list. */
+
+#ifdef emacs
+ BLOCK_INPUT;
+#endif
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* Collect garbage. */
+
+ hp = np; /* -> next header. */
+ }
+ else
+ break; /* Rest are not deeper. */
+
+ last_alloca_header = hp; /* -> last valid storage. */
+
+#ifdef emacs
+ UNBLOCK_INPUT;
+#endif
+ }
+
+ if (size == 0)
+ return NULL; /* No allocation required. */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = mymalloc (sizeof (header) + size);
+ /* Address of header. */
+
+ if (new == 0)
+ abort();
+
+ ((header *) new)->h.next = last_alloca_header;
+ ((header *) new)->h.deep = depth;
+
+ last_alloca_header = (header *) new;
+
+ /* User storage begins just after header. */
+
+ return (pointer) ((char *) new + sizeof (header));
+ }
+}
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+ {
+ long shgrow:32; /* Number of times stack has grown. */
+ long shaseg:32; /* Size of increments to stack. */
+ long shhwm:32; /* High water mark of stack. */
+ long shsize:32; /* Current size of stack (all segments). */
+ };
+
+/* The stack segment linkage control information occurs at
+ the high-address end of a stack segment. (The stack
+ grows from low addresses to high addresses.) The initial
+ part of the stack segment linkage control information is
+ 0200 (octal) words. This provides for register storage
+ for the routine which overflows the stack. */
+
+struct stack_segment_linkage
+ {
+ long ss[0200]; /* 0200 overflow words. */
+ long sssize:32; /* Number of words in this segment. */
+ long ssbase:32; /* Offset to stack base. */
+ long:32;
+ long sspseg:32; /* Offset to linkage control of previous
+ segment of stack. */
+ long:32;
+ long sstcpt:32; /* Pointer to task common address block. */
+ long sscsnm; /* Private control structure number for
+ microtasking. */
+ long ssusr1; /* Reserved for user. */
+ long ssusr2; /* Reserved for user. */
+ long sstpid; /* Process ID for pid based multi-tasking. */
+ long ssgvup; /* Pointer to multitasking thread giveup. */
+ long sscray[7]; /* Reserved for Cray Research. */
+ long ssa0;
+ long ssa1;
+ long ssa2;
+ long ssa3;
+ long ssa4;
+ long ssa5;
+ long ssa6;
+ long ssa7;
+ long sss0;
+ long sss1;
+ long sss2;
+ long sss3;
+ long sss4;
+ long sss5;
+ long sss6;
+ long sss7;
+ };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+ returned by the STKSTAT library routine. */
+struct stk_stat
+ {
+ long now; /* Current total stack size. */
+ long maxc; /* Amount of contiguous space which would
+ be required to satisfy the maximum
+ stack demand to date. */
+ long high_water; /* Stack high-water mark. */
+ long overflows; /* Number of stack overflow ($STKOFEN) calls. */
+ long hits; /* Number of internal buffer hits. */
+ long extends; /* Number of block extensions. */
+ long stko_mallocs; /* Block allocations by $STKOFEN. */
+ long underflows; /* Number of stack underflow calls ($STKRETN). */
+ long stko_free; /* Number of deallocations by $STKRETN. */
+ long stkm_free; /* Number of deallocations by $STKMRET. */
+ long segments; /* Current number of stack segments. */
+ long maxs; /* Maximum number of stack segments so far. */
+ long pad_size; /* Stack pad size. */
+ long current_address; /* Current stack segment address. */
+ long current_size; /* Current stack segment size. This
+ number is actually corrupted by STKSTAT to
+ include the fifteen word trailer area. */
+ long initial_address; /* Address of initial segment. */
+ long initial_size; /* Size of initial segment. */
+ };
+
+/* The following structure describes the data structure which trails
+ any stack segment. I think that the description in 'asdef' is
+ out of date. I only describe the parts that I am sure about. */
+
+struct stk_trailer
+ {
+ long this_address; /* Address of this block. */
+ long this_size; /* Size of this block (does not include
+ this trailer). */
+ long unknown2;
+ long unknown3;
+ long link; /* Address of trailer block of previous
+ segment. */
+ long unknown5;
+ long unknown6;
+ long unknown7;
+ long unknown8;
+ long unknown9;
+ long unknown10;
+ long unknown11;
+ long unknown12;
+ long unknown13;
+ long unknown14;
+ };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+ I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+ struct stk_stat status;
+ struct stk_trailer *trailer;
+ long *block, size;
+ long result = 0;
+
+ /* We want to iterate through all of the segments. The first
+ step is to get the stack status structure. We could do this
+ more quickly and more directly, perhaps, by referencing the
+ $LM00 common block, but I know that this works. */
+
+ STKSTAT (&status);
+
+ /* Set up the iteration. */
+
+ trailer = (struct stk_trailer *) (status.current_address
+ + status.current_size
+ - 15);
+
+ /* There must be at least one stack segment. Therefore it is
+ a fatal error if "trailer" is null. */
+
+ if (trailer == 0)
+ abort ();
+
+ /* Discard segments that do not contain our argument address. */
+
+ while (trailer != 0)
+ {
+ block = (long *) trailer->this_address;
+ size = trailer->this_size;
+ if (block == 0 || size == 0)
+ abort ();
+ trailer = (struct stk_trailer *) trailer->link;
+ if ((block <= address) && (address < (block + size)))
+ break;
+ }
+
+ /* Set the result to the offset in this segment and add the sizes
+ of all predecessor segments. */
+
+ result = address - block;
+
+ if (trailer == 0)
+ {
+ return result;
+ }
+
+ do
+ {
+ if (trailer->this_size <= 0)
+ abort ();
+ result += trailer->this_size;
+ trailer = (struct stk_trailer *) trailer->link;
+ }
+ while (trailer != 0);
+
+ /* We are done. Note that if you present a bogus address (one
+ not in any segment), you will get a different number back, formed
+ from subtracting the address of the first block. This is probably
+ not what you want. */
+
+ return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+ Determine the number of the cell within the stack,
+ given the address of the cell. The purpose of this
+ routine is to linearize, in some sense, stack addresses
+ for alloca. */
+
+static long
+i00afunc (long address)
+{
+ long stkl = 0;
+
+ long size, pseg, this_segment, stack;
+ long result = 0;
+
+ struct stack_segment_linkage *ssptr;
+
+ /* Register B67 contains the address of the end of the
+ current stack segment. If you (as a subprogram) store
+ your registers on the stack and find that you are past
+ the contents of B67, you have overflowed the segment.
+
+ B67 also points to the stack segment linkage control
+ area, which is what we are really interested in. */
+
+ stkl = CRAY_STACKSEG_END ();
+ ssptr = (struct stack_segment_linkage *) stkl;
+
+ /* If one subtracts 'size' from the end of the segment,
+ one has the address of the first word of the segment.
+
+ If this is not the first segment, 'pseg' will be
+ nonzero. */
+
+ pseg = ssptr->sspseg;
+ size = ssptr->sssize;
+
+ this_segment = stkl - size;
+
+ /* It is possible that calling this routine itself caused
+ a stack overflow. Discard stack segments which do not
+ contain the target address. */
+
+ while (!(this_segment <= address && address <= stkl))
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+ if (pseg == 0)
+ break;
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ this_segment = stkl - size;
+ }
+
+ result = address - this_segment;
+
+ /* If you subtract pseg from the current end of the stack,
+ you get the address of the previous stack segment's end.
+ This seems a little convoluted to me, but I'll bet you save
+ a cycle somewhere. */
+
+ while (pseg != 0)
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ result += size;
+ }
+ return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
+#endif /* no solaris */
+#endif /* not GCC version 2 */
diff --git a/qlparser/autogen_qtui.cc b/qlparser/autogen_qtui.cc
new file mode 100644
index 0000000..408fed3
--- /dev/null
+++ b/qlparser/autogen_qtui.cc
@@ -0,0 +1,1151 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS: Automaticaly generated
+ *
+ ************************************************************/
+
+
+const QtNode::QtNodeType QtAbs::nodeType = QtNode::QT_ABS;
+
+QtAbs::QtAbs(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtAbs::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_ABS );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtAbs::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtAbsObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+
+void QtAbs::printAlgebraicExpression(ostream& s) {
+ s << "abs(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtAbs::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtAbs", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_ABS, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtAbs::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_ABS, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtAbs::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtAbs::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtAbs::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtSqrt::nodeType = QtNode::QT_SQRT;
+
+QtSqrt::QtSqrt(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtSqrt::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_SQRT );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtSqrt::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtSqrtObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtSqrt::printAlgebraicExpression(ostream& s) {
+ s << "sqrt(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtSqrt::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtSqrt", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_SQRT, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtSqrt::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_SQRT, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtSqrt::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtSqrt::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtSqrt::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtExp::nodeType = QtNode::QT_EXP;
+
+QtExp::QtExp(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtExp::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_EXP );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtExp::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtExpObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtExp::printAlgebraicExpression(ostream& s) {
+ s << "exp(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtExp::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtExp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_EXP, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtExp::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_EXP, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtExp::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtExp::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtExp::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtLog::nodeType = QtNode::QT_LOG;
+
+QtLog::QtLog(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtLog::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_LOG );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtLog::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtLogObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtLog::printAlgebraicExpression(ostream& s) {
+ s << "log(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtLog::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtLog", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_LOG, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtLog::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_LOG, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtLog::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtLog::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtLog::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtLn::nodeType = QtNode::QT_LN;
+
+QtLn::QtLn(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtLn::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_LN );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtLn::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtLnObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtLn::printAlgebraicExpression(ostream& s) {
+ s << "ln(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtLn::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtLn", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_LN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtLn::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_LN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtLn::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtLn::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtLn::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtSin::nodeType = QtNode::QT_SIN;
+
+QtSin::QtSin(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtSin::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_SIN );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtSin::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtSinObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtSin::printAlgebraicExpression(ostream& s) {
+ s << "sin(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtSin::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtSin", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_SIN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtSin::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_SIN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtSin::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtSin::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtSin::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtCos::nodeType = QtNode::QT_COS;
+
+QtCos::QtCos(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtCos::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_COS );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtCos::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtCosObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtCos::printAlgebraicExpression(ostream& s) {
+ s << "cos(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtCos::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtCos", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_COS, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtCos::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_COS, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtCos::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtCos::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtCos::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtTan::nodeType = QtNode::QT_TAN;
+
+QtTan::QtTan(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtTan::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_TAN );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtTan::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtTanObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtTan::printAlgebraicExpression(ostream& s) {
+ s << "tan(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtTan::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtTan", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_TAN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtTan::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_TAN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtTan::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtTan::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtTan::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtSinh::nodeType = QtNode::QT_SINH;
+
+QtSinh::QtSinh(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtSinh::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_SINH );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtSinh::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtSinhObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtSinh::printAlgebraicExpression(ostream& s) {
+ s << "sinh(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtSinh::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtSinh", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_SINH, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtSinh::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_SINH, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtSinh::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtSinh::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtSinh::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtCosh::nodeType = QtNode::QT_COSH;
+
+QtCosh::QtCosh(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtCosh::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_COSH );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtCosh::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtCoshObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtCosh::printAlgebraicExpression(ostream& s) {
+ s << "cosh(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtCosh::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtCosh", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_COSH, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtCosh::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_COSH, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtCosh::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtCosh::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtCosh::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtTanh::nodeType = QtNode::QT_TANH;
+
+QtTanh::QtTanh(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtTanh::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_TANH );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtTanh::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtTanhObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtTanh::printAlgebraicExpression(ostream& s) {
+ s << "tanh(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtTanh::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtTanh", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_TANH, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtTanh::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_TANH, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtTanh::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtTanh::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtTanh::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtArcsin::nodeType = QtNode::QT_ARCSIN;
+
+QtArcsin::QtArcsin(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtArcsin::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_ARCSIN );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtArcsin::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtArcsinObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtArcsin::printAlgebraicExpression(ostream& s) {
+ s << "arcsin(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtArcsin::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtArcsin", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_ARCSIN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtArcsin::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_ARCSIN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtArcsin::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtArcsin::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtArcsin::checkType() - operand branch invalid." << endl;
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtArccos::nodeType = QtNode::QT_ARCCOS;
+
+QtArccos::QtArccos(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtArccos::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_ARCCOS );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtArccos::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtArccosObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+void QtArccos::printAlgebraicExpression(ostream& s) {
+ s << "arccos(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtArccos::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtArccos", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input) {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_ARCCOS, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtArccos::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_ARCCOS, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtArccos::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtArccos::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtArccos::checkType() - operand branch invalid." << endl;
+ return dataStreamType;
+}
+
+const QtNode::QtNodeType QtArctan::nodeType = QtNode::QT_ARCTAN;
+
+QtArctan::QtArctan(QtOperation* initInput): QtUnaryInduce(initInput) {}
+QtData* QtArctan::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand)) {
+ try {
+ returnValue = computeOp( operand, Ops::OP_ARCTAN );
+ }
+ catch(...) {
+ operand->deleteRef();
+ throw;
+ }
+ }
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtArctan::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtArctanObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+
+void QtArctan::printAlgebraicExpression(ostream& s) {
+ s << "arctan(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtArctan::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtArctan", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+ // check operand branches
+ if(input)
+ {
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "AutoGen", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_ARCTAN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtArctan::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_ARCTAN, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtArctan::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtArctan::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtArctan::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
diff --git a/qlparser/autogen_qtui.hh b/qlparser/autogen_qtui.hh
new file mode 100644
index 0000000..f3ce42d
--- /dev/null
+++ b/qlparser/autogen_qtui.hh
@@ -0,0 +1,296 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS: Automaticaly generated
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtAbs : public QtUnaryInduce {
+public:
+ QtAbs(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtSqrt : public QtUnaryInduce {
+public:
+ QtSqrt(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtExp : public QtUnaryInduce {
+public:
+ QtExp(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtLog : public QtUnaryInduce {
+public:
+ QtLog(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtLn : public QtUnaryInduce {
+public:
+ QtLn(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtSin : public QtUnaryInduce {
+public:
+ QtSin(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtCos : public QtUnaryInduce {
+public:
+ QtCos(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtTan : public QtUnaryInduce {
+public:
+ QtTan(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtSinh : public QtUnaryInduce {
+public:
+ QtSinh(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtCosh : public QtUnaryInduce {
+public:
+ QtCosh(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtTanh : public QtUnaryInduce {
+public:
+ QtTanh(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtArcsin : public QtUnaryInduce {
+public:
+ QtArcsin(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtArccos : public QtUnaryInduce {
+public:
+ QtArccos(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtArctan : public QtUnaryInduce {
+public:
+ QtArctan(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES );
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ static const QtNodeType nodeType;
+};
+
diff --git a/qlparser/autogen_qtui.icc b/qlparser/autogen_qtui.icc
new file mode 100644
index 0000000..0a339a8
--- /dev/null
+++ b/qlparser/autogen_qtui.icc
@@ -0,0 +1,44 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS: Automaticaly generated
+ *
+ ************************************************************/
+
+
+inline const QtNode::QtNodeType QtAbs::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtSqrt::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtExp::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtLog::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtLn::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtSin::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtCos::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtTan::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtSinh::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtCosh::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtTanh::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtArcsin::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtArccos::getNodeType() const { return nodeType; }
+inline const QtNode::QtNodeType QtArctan::getNodeType() const { return nodeType; }
diff --git a/qlparser/lex.ll b/qlparser/lex.ll
new file mode 100644
index 0000000..8a1b140
--- /dev/null
+++ b/qlparser/lex.ll
@@ -0,0 +1,354 @@
+%{
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ * COMMENTS:
+ * - token BY seems unused
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, lexer: $Id: oql.l,v 1.64 2005/07/06 22:48:34 rasdev Exp $";
+
+#include "qlparser/qtoperation.hh"
+#include "qlparser/querytree.hh"
+#include "qlparser/qtmddaccess.hh"
+#include "qlparser/qtcomplexdata.hh"
+#include "qlparser/qtiterator.hh"
+#include "qlparser/qtunaryinduce.hh"
+
+std::list<ParseInfo> infoList;
+
+ParseInfo *currInfo=0;
+
+struct QtUpdateSpecElement
+{
+ QtOperation* iterator;
+ QtOperation* domain;
+};
+
+#include "oql.h"
+
+QueryTree* parseQueryTree = NULL;
+char* beginParseString = NULL;
+char* iterParseString = NULL;
+void yyreset();
+
+unsigned int lineNo = 1;
+unsigned int columnNo = 1;
+void llerror( char* s );
+int yyparse( );
+
+int string_yyinput( char* buf, int max_size )
+{
+ int lenParseString = strlen( iterParseString );
+ int bufLength = max_size < lenParseString ? max_size : lenParseString;
+ if( bufLength > 0 )
+ {
+ memcpy( buf, iterParseString, bufLength );
+ iterParseString += bufLength;
+ }
+ return bufLength;
+}
+
+#undef YY_INPUT
+#define YY_INPUT( buff, buffLen, maxSize ) ( buffLen = string_yyinput( buff, maxSize ) )
+
+#define SETTOKEN( TOKEN, TYPE, VALUE ) \
+ yylval.TYPE.value = VALUE; \
+ if(!infoList.empty()) { \
+ currInfo = new ParseInfo(infoList.front()); \
+ infoList.pop_front(); \
+ } \
+ else { \
+ currInfo = new ParseInfo( yytext, lineNo, columnNo ); \
+ } \
+ yylval.TYPE.info = currInfo; \
+ columnNo += yyleng; \
+ parseQueryTree->addDynamicObject( yylval.TYPE.info ); \
+ return TOKEN;
+
+
+#define SETSTRTOKEN( TOKEN, TYPE, VALUE ) \
+ char* temp = strdup(VALUE); \
+ parseQueryTree->addCString( temp ); \
+ yylval.TYPE.value = temp; \
+ if(!infoList.empty()) { \
+ currInfo = new ParseInfo(infoList.front()); \
+ infoList.pop_front(); \
+ } \
+ else { \
+ currInfo = new ParseInfo( yytext, lineNo, columnNo ); \
+ } \
+ yylval.TYPE.info = currInfo; \
+ columnNo += yyleng; \
+ parseQueryTree->addDynamicObject( yylval.TYPE.info ); \
+ return TOKEN;
+
+
+#define SETINTTOKEN( VALUE, NEGATIVE, BYTES ) \
+ yylval.integerToken.negative = NEGATIVE; \
+ yylval.integerToken.bytes = BYTES; \
+ if( NEGATIVE ) \
+ yylval.integerToken.svalue = VALUE; \
+ else \
+ yylval.integerToken.uvalue = (unsigned long)VALUE; \
+ if(!infoList.empty()) { \
+ currInfo = new ParseInfo(infoList.front()); \
+ infoList.pop_front(); \
+ } \
+ else { \
+ currInfo = new ParseInfo( yytext, lineNo, columnNo ); \
+ } \
+ yylval.integerToken.info = currInfo; \
+ columnNo += yyleng; \
+ parseQueryTree->addDynamicObject( yylval.integerToken.info ); \
+ return IntegerLit;
+
+
+#define SETFLTTOKEN( VALUE, BYTES ) \
+ yylval.floatToken.value = VALUE; \
+ yylval.floatToken.bytes = BYTES; \
+ if(!infoList.empty()) { \
+ currInfo = new ParseInfo(infoList.front()); \
+ infoList.pop_front(); \
+ } \
+ else { \
+ currInfo = new ParseInfo(yytext, lineNo, columnNo); \
+ } \
+ yylval.floatToken.info = currInfo; \
+ columnNo += yyleng; \
+ parseQueryTree->addDynamicObject( yylval.floatToken.info ); \
+ return FloatLit;
+
+%}
+
+%option noyywrap
+
+%%
+
+"/*""/"*([^*/]|[^*]"/"|"*"[^/])*"*"*"*/" {
+ if( !strncmp( yytext, "/*+", 3 ) )
+ {
+ if( strstr( yytext, "opt 0" ) )
+ parseQueryTree->setOptimizationLevel(0);
+ if( strstr( yytext, "opt 1" ) )
+ parseQueryTree->setOptimizationLevel(1);
+ if( strstr( yytext, "opt 2" ) )
+ parseQueryTree->setOptimizationLevel(2);
+ if( strstr( yytext, "opt 3" ) )
+ parseQueryTree->setOptimizationLevel(3);
+ if( strstr( yytext, "opt 4" ) )
+ parseQueryTree->setOptimizationLevel(4);
+ }
+ columnNo += yyleng;
+ }
+"//".* { columnNo += yyleng; }
+"--".* { columnNo += yyleng; }
+
+"[opt 0]" { parseQueryTree->setOptimizationLevel(0); columnNo += yyleng; }
+"[opt 1]" { parseQueryTree->setOptimizationLevel(1); columnNo += yyleng; }
+"[opt 2]" { parseQueryTree->setOptimizationLevel(2); columnNo += yyleng; }
+"[opt 3]" { parseQueryTree->setOptimizationLevel(3); columnNo += yyleng; }
+"[opt 4]" { parseQueryTree->setOptimizationLevel(4); columnNo += yyleng; }
+
+"complex" { SETTOKEN( COMPLEX, commandToken, COMPLEX ) }
+"re" { SETTOKEN( RE, commandToken, RE ) }
+"im" { SETTOKEN( IM, commandToken, IM ) }
+
+"struct" { SETTOKEN( STRCT, commandToken, STRCT ) }
+"fastscale" { SETTOKEN( FASTSCALE, commandToken, FASTSCALE ) }
+"members" { SETTOKEN( MEMBERS, commandToken, MEMBERS ) }
+"add" { SETTOKEN( ADD, commandToken, ADD ) }
+"alter" { SETTOKEN( ALTER, commandToken, ALTER ) }
+"list" { SETTOKEN( LIST, commandToken, LIST ) }
+"select" { SETTOKEN( SELECT, commandToken, SELECT ) }
+"from" { SETTOKEN( FROM, commandToken, FROM ) }
+"where" { SETTOKEN( WHERE, commandToken, WHERE ) }
+"as" { SETTOKEN( AS, commandToken, AS ) }
+"restrict" { SETTOKEN( RESTRICT, commandToken, RESTRICT ) }
+"to" { SETTOKEN( TO, commandToken, TO ) }
+"extend" { SETTOKEN( EXTEND, commandToken, EXTEND ) }
+"by" { SETTOKEN( BY, commandToken, BY ) }
+"project" { SETTOKEN( PROJECT, commandToken, PROJECT ) }
+"at" { SETTOKEN( AT, commandToken, AT ) }
+"dimension" { SETTOKEN( DIMENSION, commandToken, DIMENSION ) }
+"all_cell"|"all_cells" { SETTOKEN( ALL, commandToken, ALL ) }
+"some_cell"|"some_cells" { SETTOKEN( SOME, commandToken, SOME ) }
+"count_cell"|"count_cells" { SETTOKEN( COUNTCELLS, commandToken, COUNTCELLS ) }
+"add_cell"|"add_cells" { SETTOKEN( ADDCELLS, commandToken, ADDCELLS ) }
+"avg_cell"|"avg_cells" { SETTOKEN( AVGCELLS, commandToken, AVGCELLS ) }
+"min_cell"|"min_cells" { SETTOKEN( MINCELLS, commandToken, MINCELLS ) }
+"max_cell"|"max_cells" { SETTOKEN( MAXCELLS, commandToken, MAXCELLS ) }
+"sdom" { SETTOKEN( SDOM, commandToken, SDOM ) }
+"over" { SETTOKEN( OVER, commandToken, OVER ) }
+"overlay" { SETTOKEN( OVERLAY, commandToken, OVERLAY ) }
+"using" { SETTOKEN( USING, commandToken, USING ) }
+"lo" { SETTOKEN( LO, commandToken, LO ) }
+"hi" { SETTOKEN( HI, commandToken, HI ) }
+
+"insert" { SETTOKEN( INSERT, commandToken, INSERT ) }
+"into" { SETTOKEN( INTO, commandToken, INTO ) }
+"values" { SETTOKEN( VALUES, commandToken, VALUES ) }
+"delete" { SETTOKEN( DELETE, commandToken, DELETE ) }
+"drop" { SETTOKEN( DROP, commandToken, DROP ) }
+"create" { SETTOKEN( CREATE, commandToken, CREATE ) }
+"collection" { SETTOKEN( COLLECTION, commandToken, COLLECTION ) }
+
+"update" { SETTOKEN( UPDATE, commandToken, UPDATE ) }
+"set" { SETTOKEN( SET, commandToken, SET ) }
+"assign" { SETTOKEN( ASSIGN, commandToken, ASSIGN ) }
+"in" { SETTOKEN( IN, commandToken, IN ) }
+"marray" { SETTOKEN( MARRAY, commandToken, MARRAY ) }
+"condense" { SETTOKEN( CONDENSE, commandToken, CONDENSE ) }
+
+"oid" { SETTOKEN( OID, commandToken, OID ) }
+"shift" { SETTOKEN( SHIFT, commandToken, SHIFT ) }
+"scale" { SETTOKEN( SCALE, commandToken, SCALE ) }
+
+"." { SETTOKEN( DOT, commandToken, DOT ) }
+"," { SETTOKEN( COMMA, commandToken, COMMA ) }
+"is" { SETTOKEN( IS, commandToken, IS ) }
+"not" { SETTOKEN( NOT, commandToken, NOT ) }
+"sqrt" { SETTOKEN( SQRT, commandToken, SQRT ) }
+
+"tiff" { SETTOKEN( TIFF, commandToken, TIFF ) }
+"bmp" { SETTOKEN( BMP, commandToken, BMP ) }
+"hdf" { SETTOKEN( HDF, commandToken, HDF ) }
+"jpeg" { SETTOKEN( JPEG, commandToken, JPEG ) }
+"csv" { SETTOKEN( CSV, commandToken, CSV ) }
+"png" { SETTOKEN( PNG, commandToken, PNG ) }
+"vff" { SETTOKEN( VFF, commandToken, VFF ) }
+"tor" { SETTOKEN( TOR, commandToken, TOR ) }
+"dem" { SETTOKEN( DEM, commandToken, DEM ) }
+
+"inv_tiff" { SETTOKEN( INV_TIFF, commandToken, INV_TIFF ) }
+"inv_bmp" { SETTOKEN( INV_BMP, commandToken, INV_BMP ) }
+"inv_hdf" { SETTOKEN( INV_HDF, commandToken, INV_HDF ) }
+"inv_jpeg" { SETTOKEN( INV_JPEG, commandToken, INV_JPEG ) }
+"inv_csv" { SETTOKEN( INV_CSV, commandToken, INV_CSV ) }
+"inv_png" { SETTOKEN( INV_PNG, commandToken, INV_PNG ) }
+"inv_vff" { SETTOKEN( INV_VFF, commandToken, INV_VFF ) }
+"inv_tor" { SETTOKEN( INV_TOR, commandToken, INV_TOR ) }
+"inv_dem" { SETTOKEN( INV_DEM, commandToken, INV_DEM ) }
+
+"abs" { SETTOKEN( ABS, commandToken, ABS ) }
+"exp" { SETTOKEN( EXP, commandToken, EXP ) }
+"log" { SETTOKEN( LOG, commandToken, LOG ) }
+"ln" { SETTOKEN( LN, commandToken, LN ) }
+"sin" { SETTOKEN( SIN, commandToken, SIN ) }
+"cos" { SETTOKEN( COS, commandToken, COS ) }
+"tan" { SETTOKEN( TAN, commandToken, TAN ) }
+"sinh" { SETTOKEN( SINH, commandToken, SINH ) }
+"cosh" { SETTOKEN( COSH, commandToken, COSH ) }
+"tanh" { SETTOKEN( TANH, commandToken, TANH ) }
+"arcsin" { SETTOKEN( ARCSIN, commandToken, ARCSIN ) }
+"arccos" { SETTOKEN( ARCCOS, commandToken, ARCCOS ) }
+"arctan" { SETTOKEN( ARCTAN, commandToken, ARCTAN ) }
+
+"unsigned" { SETTOKEN( TUNSIG, typeToken, TUNSIG) }
+"bool" { SETTOKEN( TBOOL, typeToken, TBOOL) }
+"char" { SETTOKEN( TCHAR, typeToken, TCHAR) }
+"octet" { SETTOKEN( TOCTET, typeToken, TOCTET) }
+"short" { SETTOKEN( TSHORT, typeToken, TSHORT) }
+"ushort" { SETTOKEN( TUSHORT, typeToken, TUSHORT) }
+"long" { SETTOKEN( TLONG, typeToken, TLONG) }
+"ulong" { SETTOKEN( TULONG, typeToken, TULONG) }
+"float" { SETTOKEN( TFLOAT, typeToken, TFLOAT) }
+"double" { SETTOKEN( TDOUBLE, typeToken, TDOUBLE) }
+
+"bit" { SETTOKEN( BIT, commandToken, BIT ) }
+"and" { SETTOKEN( AND, commandToken, AND ) }
+"or" { SETTOKEN( OR, commandToken, OR ) }
+"xor" { SETTOKEN( XOR, commandToken, XOR ) }
+"+" { SETTOKEN( PLUS, commandToken, PLUS ) }
+"-" { SETTOKEN( MINUS, commandToken, MINUS ) }
+"*" { SETTOKEN( MULT, commandToken, MULT ) }
+"/" { SETTOKEN( DIV, commandToken, DIV ) }
+"=" { SETTOKEN( EQUAL, commandToken, EQUAL ) }
+"<" { SETTOKEN( LESS, commandToken, LESS ) }
+">" { SETTOKEN( GREATER, commandToken, GREATER ) }
+"<=" { SETTOKEN( LESSEQUAL, commandToken, LESSEQUAL ) }
+">=" { SETTOKEN( GREATEREQUAL, commandToken, GREATEREQUAL ) }
+"<>" { SETTOKEN( NOTEQUAL, commandToken, NOTEQUAL ) }
+"!=" { SETTOKEN( NOTEQUAL, commandToken, NOTEQUAL ) }
+":" { SETTOKEN( COLON, commandToken, COLON ) }
+";" { SETTOKEN( SEMICOLON, commandToken, SEMICOLON ) }
+"[" { SETTOKEN( LEPAR, commandToken, LEPAR ) }
+"]" { SETTOKEN( REPAR, commandToken, REPAR ) }
+"(" { SETTOKEN( LRPAR, commandToken, LRPAR ) }
+")" { SETTOKEN( RRPAR, commandToken, RRPAR ) }
+"{" { SETTOKEN( LCPAR, commandToken, LCPAR ) }
+"}" { SETTOKEN( RCPAR, commandToken, RCPAR ) }
+#MDD[0-9]+# { SETTOKEN( MDDPARAM, commandToken, atoi(&(yytext[1])) ) }
+$[0-9]+ { llerror("unresolved query parameter"); columnNo++; }
+
+"true"|"false"|"TRUE"|"FALSE" { SETTOKEN( BooleanLit, booleanToken, yytext[0] == 't' || yytext[0] == 'T') }
+[a-zA-Z_][a-zA-Z0-9_]* { SETSTRTOKEN( Identifier, identifierToken, yytext ) }
+"'"[^']"'" { SETTOKEN( CharacterLit, characterToken, yytext[1] ) }
+\"([^"]|\\["\n])*\" {
+ yytext[strlen(yytext)-1] = '\0';
+ SETSTRTOKEN( StringLit, stringToken, &(yytext[1]) )
+ }
+
+0x[0-f]+[cC] { SETINTTOKEN( strtoul( yytext, (char**)NULL, 16 ), 0, 1 ) }
+0x[0-f]+"us"|"US" { SETINTTOKEN( strtoul( yytext, (char**)NULL, 16 ), 0, 2 ) }
+0x[0-f]+"ul"|"UL" { SETINTTOKEN( strtoul( yytext, (char**)NULL, 16 ), 0, 4 ) }
+-?0x[0-f]+[oO] { SETINTTOKEN( strtol ( yytext, (char**)NULL, 16 ), 1, 1 ) }
+-?0x[0-f]+[sS] { SETINTTOKEN( strtol ( yytext, (char**)NULL, 16 ), 1, 2 ) }
+-?0x[0-f]+[lL]? { SETINTTOKEN( strtol ( yytext, (char**)NULL, 16 ), 1, 4 ) }
+
+[0-9]+[cC] { SETINTTOKEN( strtoul( yytext, (char**)NULL, 10 ), 0, 1 ) }
+[0-9]+"us"|"US" { SETINTTOKEN( strtoul( yytext, (char**)NULL, 10 ), 0, 2 ) }
+[0-9]+"ul"|"UL" { SETINTTOKEN( strtoul( yytext, (char**)NULL, 10 ), 0, 4 ) }
+-?[0-9]+[oO] { SETINTTOKEN( strtol ( yytext, (char**)NULL, 10 ), 1, 1 ) }
+-?[0-9]+[sS] { SETINTTOKEN( strtol ( yytext, (char**)NULL, 10 ), 1, 2 ) }
+-?[0-9]+[lL]? { SETINTTOKEN( strtol ( yytext, (char**)NULL, 10 ), 1, 4 ) }
+
+-?([0-9]+|([0-9]+(\.[0-9]+)?)([eE][-+]?[0-9]+)?)[dD] { SETFLTTOKEN( strtod( yytext, (char**)NULL ), 8 ) }
+-?([0-9]+|([0-9]+(\.[0-9]+)?)([eE][-+]?[0-9]+)?)[fF]? { SETFLTTOKEN( strtod( yytext, (char**)NULL ), 4 ) }
+
+[ ]+ { columnNo += yyleng; }
+\t { columnNo += 3; }
+\r { }
+\n { columnNo = 1; lineNo++; }
+. { SETTOKEN(UNKNOWN, commandToken, UNKNOWN ) }
+
+%%
+
+void yyreset()
+{
+ // Reset the input buffer of the scanner so that the next call of yylex() invokes
+ // YY_INPUT to fill the buffer with new data.
+ if ( YY_CURRENT_BUFFER )
+ yy_flush_buffer( YY_CURRENT_BUFFER );
+ lineNo = 1;
+ columnNo = 1;
+ currInfo = 0;
+}
+
+
+void llerror( char* s )
+{
+ RMInit::logOut << "Lex error: line " << lineNo << ", " << s << " at " << yytext << std::endl;
+}
diff --git a/qlparser/oql.yy b/qlparser/oql.yy
new file mode 100644
index 0000000..006ed88
--- /dev/null
+++ b/qlparser/oql.yy
@@ -0,0 +1,2185 @@
+%{
+/*
+* 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:
+ * Grammar for RasQL
+ *
+ *
+ * COMMENTS:
+ * - token BY unused
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, yacc parser: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/oql.y,v 1.95 2006/01/03 00:21:40 rasdev Exp $";
+
+#include "qlparser/qtconversion.hh"
+#include "qlparser/qtmarrayop.hh"
+#include "qlparser/qtcondense.hh"
+#include "qlparser/qtbinaryinduce2.hh"
+#include "qlparser/qtbinaryfunc.hh"
+#include "qlparser/qtoid.hh"
+#include "qlparser/qtcondenseop.hh"
+#include "qlparser/qtstringdata.hh"
+#include "qlparser/qtconst.hh"
+#include "qlparser/qtintervalop.hh"
+#include "qlparser/qtmintervalop.hh"
+#include "qlparser/qtunaryfunc.hh"
+#include "qlparser/qtupdate.hh"
+#include "qlparser/qtinsert.hh"
+#include "qlparser/qtdelete.hh"
+#include "qlparser/qtjoiniterator.hh"
+#include "qlparser/qtselectioniterator.hh"
+#include "qlparser/qtoperationiterator.hh"
+#include "qlparser/qtcommand.hh"
+#include "qlparser/qtunaryinduce.hh"
+#include "qlparser/qtiterator.hh"
+#include "qlparser/qtcomplexdata.hh"
+#include "qlparser/qtmddaccess.hh"
+#include "qlparser/querytree.hh"
+#include "servercomm/servercomm.hh"
+
+extern ServerComm::ClientTblElt* currentClientTblElt;
+extern ParseInfo *currInfo;
+
+void yyerror( char* s );
+
+extern int yylex();
+extern unsigned int lineNo;
+extern unsigned int columnNo;
+extern char* yytext;
+
+//defined in oql.l
+extern QueryTree* parseQueryTree;
+
+ParseInfo* parseError = NULL;
+
+struct QtUpdateSpecElement
+{
+ QtOperation* iterator;
+ QtOperation* domain;
+};
+
+#define FREESTACK( ARG ) \
+ parseQueryTree->removeDynamicObject( ARG.info ); \
+ delete ARG.info; \
+ ARG.info=NULL;
+
+// simple context dependancy for marray
+#define YYPARSE_PARAM mflag
+#define MF_IN_CONTEXT (void *)1
+#define MF_NO_CONTEXT (void *)0
+
+%}
+
+// definition section
+
+%union {
+
+ struct {
+ bool value;
+ ParseInfo* info;
+ } booleanToken;
+
+ struct {
+ char value;
+ ParseInfo* info;
+ } characterToken;
+
+ struct {
+ unsigned short negative; // 1 = signed value, 0 = unsigned value
+ r_Long svalue; // stores the signed value -> negative = 1
+ r_ULong uvalue; // stores the unsigned value -> negative = 0;
+ unsigned short bytes; // stores the length in bytes (1,2,3,4)
+ ParseInfo* info;
+ } integerToken;
+
+ struct {
+ double value;
+ unsigned short bytes; // stores the length in bytes (4,8)
+ ParseInfo* info;
+ } floatToken;
+
+ struct {
+ char* value;
+ ParseInfo* info;
+ } stringToken;
+
+ struct {
+ int value;
+ ParseInfo* info;
+ } typeToken;
+
+
+ struct {
+ int value;
+ ParseInfo* info;
+ } commandToken;
+
+ struct {
+ char* value;
+ ParseInfo* info;
+ } identifierToken;
+
+//--------------------------------------------------
+ QtMarrayOp2::mddIntervalType * mddIntervalType;
+ QtMarrayOp2::mddIntervalListType * mddIntervalListType;
+//---------------------------------------------------
+
+ r_Sinterval* Sinterval;
+
+ QtNode* qtNodeValue;
+ QtOperation* qtOperationValue;
+ QtUnaryOperation* qtUnaryOperationValue;
+ QtDomainOperation* qtDomainValue;
+ QtMDDAccess* qtMDDAccessValue;
+
+ QtData* qtDataValue;
+ QtScalarData* qtScalarDataValue;
+ QtAtomicData* qtAtomicDataValue;
+ QtComplexData* qtComplexDataValue;
+
+ QtIterator::QtONCStreamList* qtONCStreamListValue;
+ QtComplexData::QtScalarDataList* qtScalarDataListValue;
+ QtNode::QtOperationList* qtOperationListValue;
+
+ QtUpdateSpecElement qtUpdateSpecElement;
+
+ Ops::OpType operationValue;
+ int dummyValue;
+
+ struct {
+ QtCast::cast_types qtCastType;
+ ParseInfo *info;
+ } castTypes;
+
+}
+
+%token <identifierToken> Identifier
+%token <booleanToken> BooleanLit
+%token <characterToken> CharacterLit
+%token <integerToken> IntegerLit
+%token <floatToken> FloatLit
+%token <stringToken> StringLit
+%token <typeToken> TUNSIG TBOOL TOCTET TCHAR TSHORT TUSHORT TLONG TULONG TFLOAT TDOUBLE
+%token <commandToken> SELECT FROM WHERE AS RESTRICT TO EXTEND BY PROJECT AT DIMENSION ALL SOME
+ COUNTCELLS ADDCELLS AVGCELLS MINCELLS MAXCELLS SDOM OVER USING LO HI UPDATE
+ SET ASSIGN MARRAY CONDENSE IN DOT COMMA IS NOT AND OR XOR PLUS MINUS MULT
+ DIV EQUAL LESS GREATER LESSEQUAL GREATEREQUAL NOTEQUAL COLON SEMICOLON LEPAR
+ REPAR LRPAR RRPAR LCPAR RCPAR INSERT INTO VALUES DELETE DROP CREATE COLLECTION
+ MDDPARAM OID SHIFT SCALE SQRT ABS EXP LOG LN SIN COS TAN SINH COSH TANH ARCSIN
+ ARCCOS ARCTAN OVERLAY BIT UNKNOWN FASTSCALE MEMBERS ADD ALTER LIST
+ STRCT COMPLEX RE IM TIFF BMP HDF CSV JPEG PNG VFF TOR DEM INV_TIFF INV_BMP INV_HDF
+ INV_JPEG INV_PNG INV_VFF INV_CSV INV_TOR INV_DEM
+
+%left COLON VALUES USING WHERE
+%left OVERLAY
+%left OR XOR
+%left AND
+%left NOT
+%left IS
+%left EQUAL LESS GREATER LESSEQUAL GREATEREQUAL NOTEQUAL
+%left PLUS MINUS
+%left MULT DIV
+%left UNARYOP BIT
+%left DOT LEPAR SDOM
+
+// The LEPAR precedence is for the trimming operation. Context dependent
+// precedence would be better in that case but it did not work.
+
+%type <qtUpdateSpecElement> updateSpec
+%type <qtMDDAccessValue> iteratedCollection
+%type <qtONCStreamListValue> collectionList
+%type <qtUnaryOperationValue> reduceIdent structSelection trimExp
+%type <qtOperationValue> mddExp inductionExp generalExp resultList reduceExp functionExp spatialOp
+ integerExp mintervalExp intervalExp condenseExp variable
+%type <qtOperationListValue> spatialOpList spatialOpList2
+%type <integerToken> intLitExp
+%type <operationValue> condenseOpLit
+%type <castTypes> castType
+%type <dummyValue> qlfile query selectExp createExp insertExp deleteExp updateExp dropExp
+%type <identifierToken> namedCollection collectionIterator typeName attributeIdent pyrName
+ marrayVariable condenseVariable
+
+// literal data
+%type <qtDataValue> generalLit mddLit oidLit
+%type <qtScalarDataValue> scalarLit
+%type <qtAtomicDataValue> atomicLit
+%type <qtComplexDataValue> complexLit
+%type <qtScalarDataListValue> scalarLitList dimensionLitList
+
+// marray2 with multiple intervals
+%type <mddIntervalListType> ivList
+%type <mddIntervalType> iv marray_head
+
+%% // rules section
+/*--------------------------------------------------------------------
+ * Grammar starts here
+ *--------------------------------------------------------------------
+ */
+
+qlfile: query
+ {
+ // clear all symbols in table at the end of parsing
+ QueryTree::symtab.wipe();
+ };
+
+query: createExp
+ | dropExp
+ | selectExp
+ | updateExp
+ | insertExp
+ | deleteExp;
+
+
+createExp: CREATE COLLECTION namedCollection typeName
+ {
+ try {
+ accessControl.wantToWrite();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $2.info->getToken().c_str(),
+ $2.info->getLineNo(), $2.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ FREESTACK($4)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // create the command node
+ QtCommand* commandNode = new QtCommand( QtCommand::QT_CREATE_COLLECTION, $3.value, $4.value );
+ commandNode->setParseInfo( *($1.info) );
+
+ // set insert node as root of the Query Tree
+ parseQueryTree->setRoot( commandNode );
+
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ FREESTACK($4)
+ };
+
+dropExp: DROP COLLECTION namedCollection
+ {
+ try {
+ accessControl.wantToWrite();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $2.info->getToken().c_str(),
+ $2.info->getLineNo(), $2.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // create the command node
+ QtCommand* commandNode = new QtCommand( QtCommand::QT_DROP_COLLECTION, $3.value );
+ commandNode->setParseInfo( *($1.info) );
+
+ // set insert node as root of the Query Tree
+ parseQueryTree->setRoot( commandNode );
+
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ };
+
+selectExp: SELECT resultList FROM collectionList WHERE generalExp
+ {
+ try {
+ accessControl.wantToRead();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $1.info->getToken().c_str(),
+ $1.info->getLineNo(), $1.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($3)
+ FREESTACK($5)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ for( QtIterator::QtONCStreamList::iterator iter=$4->begin(); iter!=$4->end(); iter++ )
+ parseQueryTree->removeDynamicObject( *iter );
+
+ // create a JoinIterator
+ QtJoinIterator* ji = new QtJoinIterator();
+ ji->setStreamInputs( $4 );
+ parseQueryTree->removeDynamicObject( $4 );
+
+ // create a QtONCStreamList and add the Join Iterator
+ QtIterator::QtONCStreamList* inputListS = new QtIterator::QtONCStreamList(1);
+ (*inputListS)[0] = ji;
+
+ // create a SelectionIterator
+ QtSelectionIterator* si = new QtSelectionIterator();
+ si->setStreamInputs( inputListS );
+ si->setParseInfo( *($5.info) );
+ si->setConditionTree( $6 );
+ parseQueryTree->removeDynamicObject( $6 );
+
+ // create a QtONCStreamList and add the Selection Iterator
+ QtIterator::QtONCStreamList* inputListO = new QtIterator::QtONCStreamList(1);
+ (*inputListO)[0] = si;
+
+ // create a OperationIterator and set its inputs
+ QtOperationIterator* oi = new QtOperationIterator();
+ oi->setStreamInputs( inputListO );
+ oi->setParseInfo( *($1.info) );
+ oi->setOperationTree( $2 );
+ parseQueryTree->removeDynamicObject( $2 );
+
+ // set the OperationIterator as root of the Query Tree
+ parseQueryTree->setRoot( oi );
+
+ FREESTACK($1)
+ FREESTACK($3)
+ FREESTACK($5)
+ }
+ | SELECT resultList FROM collectionList
+ {
+ try {
+ accessControl.wantToRead();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $1.info->getToken().c_str(),
+ $1.info->getLineNo(), $1.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($3)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ for( QtIterator::QtONCStreamList::iterator iter=$4->begin(); iter!=$4->end(); iter++ )
+ parseQueryTree->removeDynamicObject( *iter );
+
+ // create a JoinIterator
+ QtJoinIterator* ji = new QtJoinIterator();
+ ji->setStreamInputs( $4 );
+ parseQueryTree->removeDynamicObject( $4 );
+
+ // create a QtONCStreamList and add the Join Iterator
+ QtIterator::QtONCStreamList* inputList = new QtIterator::QtONCStreamList(1);
+ (*inputList)[0] = ji;
+
+ // create a OperationIterator and set its inputs
+ QtOperationIterator* oi = new QtOperationIterator();
+ oi->setStreamInputs( inputList );
+ oi->setParseInfo( *($1.info) );
+ oi->setOperationTree( $2 );
+ parseQueryTree->removeDynamicObject( $2 );
+
+ // set the OperationIterator as root of the Query Tree
+ parseQueryTree->setRoot( oi );
+
+ FREESTACK($1)
+ FREESTACK($3)
+ };
+
+updateExp: UPDATE iteratedCollection SET updateSpec ASSIGN generalExp WHERE generalExp
+ {
+ try {
+ accessControl.wantToWrite();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $1.info->getToken().c_str(),
+ $1.info->getLineNo(), $1.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($3)
+ FREESTACK($5)
+ FREESTACK($7)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // create a QtONCStreamList and add the QtAccess object of collection Spec
+ QtIterator::QtONCStreamList* streamList = new QtIterator::QtONCStreamList(1);
+ (*streamList)[0] = $2;
+ parseQueryTree->removeDynamicObject( $2 );
+
+ // create a SelectionIterator
+ QtSelectionIterator* si = new QtSelectionIterator();
+ si->setStreamInputs( streamList );
+ si->setConditionTree( $8 );
+ si->setParseInfo( *($7.info) );
+ parseQueryTree->removeDynamicObject( $8 );
+
+ // create an update node
+ QtUpdate* update = new QtUpdate( $4.iterator, $4.domain, $6 );
+ update->setStreamInput( si );
+ update->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $4.iterator );
+ parseQueryTree->removeDynamicObject( $4.domain );
+ parseQueryTree->removeDynamicObject( $6 );
+
+ // set the update node as root of the Query Tree
+ parseQueryTree->setRoot( update );
+
+ FREESTACK($1)
+ FREESTACK($3)
+ FREESTACK($5)
+ FREESTACK($7)
+ }
+ | UPDATE iteratedCollection SET updateSpec ASSIGN generalExp
+ {
+ try {
+ accessControl.wantToWrite();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $1.info->getToken().c_str(),
+ $1.info->getLineNo(), $1.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($3)
+ FREESTACK($5)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // create an update node
+ QtUpdate* update = new QtUpdate( $4.iterator, $4.domain, $6 );
+ update->setStreamInput( $2 );
+ update->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $2 );
+ parseQueryTree->removeDynamicObject( $4.iterator );
+ parseQueryTree->removeDynamicObject( $4.domain );
+ parseQueryTree->removeDynamicObject( $6 );
+
+ // set the update node as root of the Query Tree
+ parseQueryTree->setRoot( update );
+
+ FREESTACK($1)
+ FREESTACK($3)
+ FREESTACK($5)
+ };
+
+insertExp: INSERT INTO namedCollection VALUES generalExp
+ {
+ try {
+ accessControl.wantToWrite();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $2.info->getToken().c_str(),
+ $2.info->getLineNo(), $2.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ FREESTACK($4)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // create an update node
+ QtInsert* insert = new QtInsert( $3.value, $5 );
+ insert->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $5 );
+
+ // set insert node as root of the Query Tree
+ parseQueryTree->setRoot( insert );
+
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ FREESTACK($4)
+ };
+
+deleteExp: DELETE FROM iteratedCollection WHERE generalExp
+ {
+ try {
+ accessControl.wantToWrite();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $2.info->getToken().c_str(),
+ $2.info->getLineNo(), $2.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // create a QtONCStreamList and add the QtAccess object of collection Spec
+ QtIterator::QtONCStreamList* streamList = new QtIterator::QtONCStreamList(1);
+ (*streamList)[0] = $3;
+ parseQueryTree->removeDynamicObject( $3 );
+
+ // create a SelectionIterator
+ QtSelectionIterator* si = new QtSelectionIterator();
+ si->setStreamInputs( streamList );
+ si->setConditionTree( $5 );
+ si->setParseInfo( *($4.info) );
+ parseQueryTree->removeDynamicObject( $5 );
+
+ // create delete node
+ QtDelete* delNode = new QtDelete();
+ delNode->setStreamInput( si );
+ delNode->setParseInfo( *($1.info) );
+
+ // set insert node as root of the Query Tree
+ parseQueryTree->setRoot( delNode );
+
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+/* // doesn't work yet, somewhere later the server crashes -- PB 2006-jan-03
+ | DELETE FROM iteratedCollection
+ {
+ try {
+ accessControl.wantToWrite();
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 803, $2.info->getToken().c_str(),
+ $2.info->getLineNo(), $2.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($2)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // create delete node
+ QtDelete* delNode = new QtDelete();
+ delNode->setStreamInput( $3 );
+ delNode->setParseInfo( *($1.info) );
+
+ // set insert node as root of the Query Tree
+ parseQueryTree->setRoot( delNode );
+
+ FREESTACK($1)
+ FREESTACK($2)
+ }
+*/
+ ;
+
+updateSpec: variable
+ {
+ $$.iterator = $1;
+ $$.domain = 0;
+ }
+ | variable mintervalExp
+ {
+ $$.iterator = $1;
+ $$.domain = $2;
+ };
+
+resultList: resultList COMMA generalExp
+ {
+ $$ = $3;
+ FREESTACK($2)
+ }
+ | generalExp
+ {
+ $$ = $1;
+ };
+
+generalExp: mddExp { $$ = $1; }
+ | trimExp { $$ = $1; }
+ | reduceExp { $$ = $1; }
+ | inductionExp { $$ = $1; }
+ | functionExp { $$ = $1; }
+ | integerExp { $$ = $1; }
+ | condenseExp { $$ = $1; }
+ | variable { $$ = $1; }
+ | mintervalExp { $$ = $1; }
+ | intervalExp { $$ = $1; }
+ | generalLit
+ {
+ $$ = new QtConst( $1 );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->addDynamicObject( $$ );
+ };
+
+integerExp: generalExp DOT LO
+ {
+ $$ = new QtIntervalLoOp( $1 );
+ $$->setParseInfo( *($3.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ FREESTACK($3)
+ }
+ | generalExp DOT HI
+ {
+ $$ = new QtIntervalHiOp( $1 );
+ $$->setParseInfo( *($3.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ FREESTACK($3)
+ };
+
+mintervalExp: LEPAR spatialOpList REPAR
+ {
+ if (($2->size() > 1) ||
+ ($2->size() == 1 && (*$2)[0]->getNodeType() == QtNode::QT_INTERVALOP))
+ {
+ // Check if the list consists of integers only and
+ // create a point operation in this case.
+ int isPoint = 1;
+ QtNode::QtOperationList::iterator iter;
+
+ for( iter=$2->begin(); iter!=$2->end(); ++iter )
+ isPoint &= (*iter)->getNodeType() != QtNode::QT_INTERVALOP;
+
+ for( iter=$2->begin(); iter!=$2->end(); ++iter )
+ parseQueryTree->removeDynamicObject( *iter );
+
+ if( isPoint )
+ $$ = new QtPointOp( $2 );
+ else
+ $$ = new QtMintervalOp( $2 );
+
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ }
+ else
+ if ($2->size() == 1)
+ {
+ // take the single element
+ $$ = (*$2)[0];
+ (*$2)[0] = 0;
+ delete $2;
+ }
+ else
+ {
+ RMInit::logOut << "MINTERVAL error: empty expression between brackets encountered!" << std::endl;
+ // save the parse error info and stop the parser
+ if ( parseError )
+ delete parseError;
+ // TODO: Define an error number for this one!!!! 312 is not correct.
+ parseError = new ParseInfo( 312, $1.info->getToken().c_str(),
+ $1.info->getLineNo(),
+ $1.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($3)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+ FREESTACK($1)
+ FREESTACK($3)
+ }
+ | SDOM LRPAR collectionIterator RRPAR
+ {
+ QtVariable* var = new QtVariable( $3.value );
+ var->setParseInfo( *($3.info) );
+ $$ = new QtSDom( var );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ FREESTACK($4)
+ };
+
+spatialOpList:
+ {
+ $$ = new QtNode::QtOperationList();
+ }
+ | spatialOpList2
+ {
+ $$ = $1;
+ };
+
+spatialOpList2: spatialOpList2 COMMA spatialOp
+ {
+ $1->push_back( $3 );
+ $$ = $1;
+ FREESTACK($2)
+ }
+ | spatialOp
+ {
+ $$ = new QtNode::QtOperationList(1);
+ (*$$)[0] = $1;
+ };
+
+spatialOp: generalExp { $$ = $1; };
+
+intervalExp: generalExp COLON generalExp
+ {
+ $$ = new QtIntervalOp( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | MULT COLON generalExp
+ {
+ QtConst* const1 = new QtConst( new QtStringData("*") );
+ const1->setParseInfo( *($1.info) );
+ $$ = new QtIntervalOp( const1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ }
+ | generalExp COLON MULT
+ {
+ QtConst* const1 = new QtConst( new QtStringData("*") );
+ const1->setParseInfo( *($3.info) );
+ $$ = new QtIntervalOp( $1, const1 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ FREESTACK($3)
+ }
+ | MULT COLON MULT
+ {
+ QtConst* const1 = new QtConst( new QtStringData("*") );
+ const1->setParseInfo( *($1.info) );
+ QtConst* const2 = new QtConst( new QtStringData("*") );
+ const2->setParseInfo( *($3.info) );
+ $$ = new QtIntervalOp( const1, const2 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ };
+
+condenseExp: CONDENSE condenseOpLit OVER condenseVariable IN generalExp WHERE generalExp USING generalExp
+ {
+ $$ = new QtCondenseOp( $2, $4.value, $6, $10, $8 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $6 );
+ parseQueryTree->removeDynamicObject( $8 );
+ parseQueryTree->removeDynamicObject( $10 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($3)
+ FREESTACK($4)
+ FREESTACK($5)
+ FREESTACK($7)
+ FREESTACK($9)
+ }
+ | CONDENSE condenseOpLit OVER condenseVariable IN generalExp USING generalExp
+ {
+ $$ = new QtCondenseOp( $2, $4.value, $6, $8 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $6 );
+ parseQueryTree->removeDynamicObject( $8 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($3)
+ FREESTACK($4)
+ FREESTACK($5)
+ FREESTACK($7)
+ };
+
+condenseOpLit: PLUS
+ {
+ $$ = Ops::OP_PLUS;
+ FREESTACK($1)
+ }
+ | MINUS
+ {
+ $$ = Ops::OP_MINUS;
+ FREESTACK($1)
+ }
+ | MULT
+ {
+ $$ = Ops::OP_MULT;
+ FREESTACK($1)
+ }
+ | DIV
+ {
+ $$ = Ops::OP_DIV;
+ FREESTACK($1)
+ }
+ | AND
+ {
+ $$ = Ops::OP_AND;
+ FREESTACK($1)
+ }
+ | OR
+ {
+ $$ = Ops::OP_OR;
+ FREESTACK($1)
+ };
+
+functionExp: OID LRPAR collectionIterator RRPAR
+ {
+ QtVariable* var = new QtVariable( $3.value );
+ var->setParseInfo( *($3.info) );
+ $$ = new QtOId( var );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ FREESTACK($4)
+ }
+ | SHIFT LRPAR generalExp COMMA generalExp RRPAR
+ {
+ $$ = new QtShift( $3, $5 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->removeDynamicObject( $5 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ // added -- PB 2005-jun-18
+ | EXTEND LRPAR generalExp COMMA generalExp RRPAR
+ {
+ $$ = new QtExtend( $3, $5 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->removeDynamicObject( $5 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | SCALE LRPAR generalExp COMMA generalExp RRPAR
+ {
+ $$ = new QtScale( $3, $5 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->removeDynamicObject( $5 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | BIT LRPAR generalExp COMMA generalExp RRPAR
+ {
+ $$ = new QtBit( $3, $5 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->removeDynamicObject( $5 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | TIFF LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOTIFF, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | TIFF LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOTIFF );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | BMP LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOBMP, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | BMP LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOBMP );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | HDF LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOHDF, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | HDF LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOHDF );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | CSV LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOCSV, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | CSV LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOCSV );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | JPEG LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOJPEG, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | JPEG LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOJPEG );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | PNG LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOPNG, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | PNG LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOPNG );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | VFF LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOVFF, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | VFF LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOVFF );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | TOR LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOTOR, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | TOR LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TOTOR );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | DEM LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TODEM, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | DEM LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_TODEM );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_TIFF LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMTIFF, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_TIFF LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMTIFF );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_BMP LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMBMP, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_BMP LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMBMP );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_HDF LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMHDF, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_HDF LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMHDF );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_CSV LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMCSV, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_CSV LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMCSV );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_JPEG LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMJPEG, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_JPEG LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMJPEG );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_PNG LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMPNG, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_PNG LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMPNG );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_VFF LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMVFF, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_VFF LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMVFF );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_TOR LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMTOR, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_TOR LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMTOR );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | INV_DEM LRPAR generalExp COMMA StringLit RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMDEM, $5.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ }
+ | INV_DEM LRPAR generalExp RRPAR
+ {
+ $$ = new QtConversion( $3, QtConversion::QT_FROMDEM );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ };
+
+
+structSelection: DOT attributeIdent
+ {
+ $$ = new QtDot( $2.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ }
+ | DOT intLitExp
+ {
+ if( $2.negative )
+ if( $2.svalue < 0 )
+ yyerror("non negative integer expected");
+ else
+ $$ = new QtDot( (unsigned int)$2.svalue );
+ else
+ $$ = new QtDot( (unsigned int)$2.uvalue );
+ parseQueryTree->addDynamicObject( $$ );
+ $$->setParseInfo( *($1.info) );
+ FREESTACK($1)
+ FREESTACK($2)
+ };
+
+inductionExp: SQRT LRPAR generalExp RRPAR
+ {
+ $$ = new QtSqrt( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | ABS LRPAR generalExp RRPAR
+ {
+ $$ = new QtAbs( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | EXP LRPAR generalExp RRPAR
+ {
+ $$ = new QtExp( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | LOG LRPAR generalExp RRPAR
+ {
+ $$ = new QtLog( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | LN LRPAR generalExp RRPAR
+ {
+ $$ = new QtLn( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | SIN LRPAR generalExp RRPAR
+ {
+ $$ = new QtSin( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | COS LRPAR generalExp RRPAR
+ {
+ $$ = new QtCos( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | TAN LRPAR generalExp RRPAR
+ {
+ $$ = new QtTan( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | SINH LRPAR generalExp RRPAR
+ {
+ $$ = new QtSinh( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | COSH LRPAR generalExp RRPAR
+ {
+ $$ = new QtCosh( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | TANH LRPAR generalExp RRPAR
+ {
+ $$ = new QtTanh( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | ARCSIN LRPAR generalExp RRPAR
+ {
+ $$ = new QtArcsin( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | ARCCOS LRPAR generalExp RRPAR
+ {
+ $$ = new QtArccos( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | ARCTAN LRPAR generalExp RRPAR
+ {
+ $$ = new QtArctan( $3 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ }
+ | generalExp DOT RE
+ {
+ $$ = new QtRealPartOp( $1 );
+ $$->setParseInfo( *($3.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ FREESTACK($3)
+ }
+ | generalExp DOT IM
+ {
+ $$ = new QtImaginarPartOp( $1 );
+ $$->setParseInfo( *($3.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ FREESTACK($3)
+ }
+ | NOT generalExp
+ {
+ $$ = new QtNot( $2 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->removeDynamicObject( $2 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | generalExp OVERLAY generalExp
+ {
+ $$ = new QtOverlay ( $3, $1 );
+ $$->setParseInfo( *($2.info) );
+ FREESTACK($2)
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ }
+ | generalExp IS generalExp
+ {
+ $$ = new QtIs ( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp AND generalExp
+ {
+ $$ = new QtAnd( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp OR generalExp
+ {
+ $$ = new QtOr ( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp XOR generalExp
+ {
+ $$ = new QtXor( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp PLUS generalExp
+ {
+ $$ = new QtPlus ( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp MINUS generalExp
+ {
+ $$ = new QtMinus( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp MULT generalExp
+ {
+ $$ = new QtMult ( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp DIV generalExp
+ {
+ $$ = new QtDiv ( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp EQUAL generalExp
+ {
+ $$ = new QtEqual( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ FREESTACK($2)
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ }
+ | generalExp LESS generalExp
+ {
+ $$ = new QtLess( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp GREATER generalExp
+ {
+ $$ = new QtLess( $3, $1 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp LESSEQUAL generalExp
+ {
+ $$ = new QtLessEqual( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp GREATEREQUAL generalExp
+ {
+ $$ = new QtLessEqual( $3, $1 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | generalExp NOTEQUAL generalExp
+ {
+ $$ = new QtNotEqual ( $1, $3 );
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | PLUS generalExp %prec UNARYOP
+ {
+ $$ = $2;
+ FREESTACK($1)
+ }
+ | MINUS generalExp %prec UNARYOP
+ {
+ $$ = new QtMult( $2, new QtConst( new QtAtomicData( (r_Long)-1, 1 ) ) );
+ parseQueryTree->removeDynamicObject( $2 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | LRPAR castType RRPAR generalExp %prec UNARYOP
+ {
+ $$ = new QtCast($4, $2.qtCastType);
+ $$->setParseInfo( *($2.info) );
+ parseQueryTree->removeDynamicObject($4);
+ parseQueryTree->addDynamicObject($$);
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ }
+ | LRPAR generalExp RRPAR
+ {
+ $$ = $2;
+ FREESTACK($1)
+ FREESTACK($3)
+ }
+ | generalExp structSelection
+ {
+ $2->setInput($1);
+ $$ = $2;
+ parseQueryTree->removeDynamicObject( $1 );
+ };
+
+castType: TBOOL { $$.info = $1.info; $$.qtCastType = QtCast::t_bool; }
+ | TCHAR { $$.info = $1.info; $$.qtCastType = QtCast::t_char; }
+ | TOCTET { $$.info = $1.info; $$.qtCastType = QtCast::t_octet; }
+ | TSHORT { $$.info = $1.info; $$.qtCastType = QtCast::t_short; }
+ | TUSHORT { $$.info = $1.info; $$.qtCastType = QtCast::t_ushort; }
+ | TLONG { $$.info = $1.info; $$.qtCastType = QtCast::t_long; }
+ | TULONG { $$.info = $1.info; $$.qtCastType = QtCast::t_ulong; }
+ | TFLOAT { $$.info = $1.info; $$.qtCastType = QtCast::t_float; }
+ | TDOUBLE { $$.info = $1.info; $$.qtCastType = QtCast::t_double; }
+ | TUNSIG TSHORT { $$.info = $1.info; $$.qtCastType = QtCast::t_ushort; }
+ | TUNSIG TLONG { $$.info = $1.info; $$.qtCastType = QtCast::t_ulong; };
+
+collectionList: collectionList COMMA iteratedCollection
+ {
+ // add the QtMDDAccess object and give back the list
+ $1->push_back($3);
+ $$ = $1;
+ FREESTACK($2)
+ }
+ | iteratedCollection
+ {
+ // create a new list and add the QtMDDAccess object
+ $$ = new QtIterator::QtONCStreamList();
+ $$->push_back($1);
+ parseQueryTree->addDynamicObject( $$ );
+ };
+
+iteratedCollection: namedCollection AS collectionIterator
+ {
+ $$ = new QtMDDAccess( $1.value, $3.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ }
+ | namedCollection collectionIterator
+ {
+ $$ = new QtMDDAccess( $1.value, $2.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ }
+ | namedCollection
+ {
+ $$ = new QtMDDAccess( $1.value, $1.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ };
+
+variable: Identifier
+ {
+ $$ = new QtVariable( $1.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ };
+
+namedCollection: Identifier;
+
+collectionIterator: Identifier;
+
+pyrName: Identifier;
+
+attributeIdent: Identifier;
+
+typeName: Identifier;
+
+marrayVariable: Identifier;
+
+condenseVariable: Identifier;
+
+reduceExp: reduceIdent LRPAR generalExp RRPAR
+ {
+ $1->setInput( $3 );
+ $$ = $1;
+ parseQueryTree->removeDynamicObject( $3 );
+ FREESTACK($2)
+ FREESTACK($4)
+ };
+
+reduceIdent: ALL
+ {
+ $$ = new QtAll();
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | SOME
+ {
+ $$ = new QtSome();
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | COUNTCELLS
+ {
+ $$ = new QtCountCells();
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | ADDCELLS
+ {
+ $$ = new QtAddCells();
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | AVGCELLS
+ {
+ $$ = new QtAvgCells();
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | MINCELLS
+ {
+ $$ = new QtMinCells();
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | MAXCELLS
+ {
+ $$ = new QtMaxCells();
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ };
+
+intLitExp: IntegerLit { $$ = $1; };
+
+generalLit: scalarLit { $$ = $1; }
+ | mddLit { $$ = $1; }
+ | StringLit
+ {
+ $$ = new QtStringData( std::string($1.value) );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | oidLit { $$ = $1; };
+
+oidLit: LESS StringLit GREATER
+ {
+ r_OId oid;
+ try {
+ oid = r_OId( $2.value );
+ }
+ catch(...) {
+ // save the parse error info and stop the parser
+ if ( parseError ) delete parseError;
+ parseError = new ParseInfo( 303, $2.info->getToken().c_str(),
+ $2.info->getLineNo(), $2.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // test if database match the current one
+ int mismatch = oid.get_base_name() == 0;
+
+ if( !mismatch ) {
+ // check for question mark
+ char* baseName = strdup( oid.get_base_name() );
+ char* end = strchr( baseName, '?' );
+ if( end )
+ *end = '\0';
+ mismatch = strcmp( baseName, currentClientTblElt->database.getName() ) !=0;
+ free( baseName );
+ baseName = 0;
+ }
+
+ if( mismatch ) {
+ // save the parse error info and stop the parser
+ if( parseError ) delete parseError;
+ parseError = new ParseInfo( 386, $2.info->getToken().c_str(),
+ $2.info->getLineNo(), $2.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+
+ // take the local oid
+ $$ = new QtAtomicData( oid.get_local_oid(), 8 );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($3)
+ };
+
+mddLit: LESS mintervalExp dimensionLitList GREATER
+ {
+ // create a QtMDD object representing the literal
+ try {
+ $$ = new QtMDD( $2, $3 );
+ }
+ catch( ParseInfo& obj ) {
+ delete $3;
+
+ // save the parse error info and stop the parser
+ if( parseError ) delete parseError;
+ parseError = new ParseInfo( obj.getErrorNo(), $1.info->getToken().c_str(),
+ $1.info->getLineNo(), $1.info->getColumnNo() );
+ FREESTACK($1)
+ FREESTACK($4)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+ $$->setParseInfo( *($1.info) );
+
+ for( std::list<QtScalarData*>::iterator iter=$3->begin(); iter!=$3->end(); iter++ ) {
+ delete *iter;
+ parseQueryTree->removeDynamicObject( *iter );
+ }
+
+ delete $2;
+ delete $3;
+ parseQueryTree->removeDynamicObject( $2 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($4)
+ }
+ | MDDPARAM
+ {
+ try {
+ $$ = new QtMDD( $1.value );
+ }
+ catch( ParseInfo& obj ) {
+ // save the parse error info and stop the parser
+ if( parseError ) delete parseError;
+ parseError = new ParseInfo( obj.getErrorNo(), $1.info->getToken().c_str(),
+ $1.info->getLineNo(), $1.info->getColumnNo() );
+ FREESTACK($1)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+ parseQueryTree->addDynamicObject( $$ );
+ $$->setParseInfo( *($1.info) );
+ FREESTACK($1)
+ };
+
+dimensionLitList: dimensionLitList SEMICOLON scalarLitList
+ {
+ // concatenate the lists
+ $1->splice( $1->end(), *$3 );
+ $$ = $1;
+ delete $3;
+ FREESTACK($2)
+ }
+ | scalarLitList
+ {
+ // simply take the list
+ $$ = $1;
+ };
+
+scalarLit: complexLit
+ {
+ $$ = $1;
+ }
+ | atomicLit
+ {
+ $$ = $1;
+ };
+
+atomicLit: BooleanLit
+ {
+ $$ = new QtAtomicData( $1.value );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | IntegerLit
+ {
+ if( $1.negative )
+ $$ = new QtAtomicData( $1.svalue, $1.bytes );
+ else
+ $$ = new QtAtomicData( $1.uvalue, $1.bytes );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | FloatLit
+ {
+ $$ = new QtAtomicData( $1.value, $1.bytes );
+ $$->setParseInfo( *($1.info) );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ }
+ | COMPLEX LRPAR FloatLit COMMA FloatLit RRPAR
+ {
+ // this should construct a complex type
+ // for both float and double cell type
+ if($3.bytes + $5.bytes == 2 * sizeof(float) || $3.bytes + $5.bytes == 2 * sizeof(double))
+ $$ = new QtAtomicData($3.value, $5.value, $3.bytes + $5.bytes);
+ else {
+ if(parseError) delete parseError;
+ parseError = new ParseInfo(311, $2.info->getToken().c_str(),
+ $2.info->getLineNo(), $2.info->getColumnNo());
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+ $$->setParseInfo(*($3.info));
+ parseQueryTree->addDynamicObject($$);
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ FREESTACK($6)
+ };
+
+complexLit: LCPAR scalarLitList RCPAR
+ {
+ for( std::list<QtScalarData*>::iterator iter=$2->begin(); iter!=$2->end(); iter++ )
+ parseQueryTree->removeDynamicObject( *iter );
+ $$ = new QtComplexData( $2 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($3)
+ }
+ | STRCT LCPAR scalarLitList RCPAR
+ {
+ for( std::list<QtScalarData*>::iterator iter=$3->begin(); iter!=$3->end(); iter++ )
+ parseQueryTree->removeDynamicObject( *iter );
+ $$ = new QtComplexData( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($1)
+ FREESTACK($2)
+ FREESTACK($4)
+ };
+
+scalarLitList: scalarLitList COMMA scalarLit
+ {
+ // add the literal element and give back the list
+ $1->push_back($3);
+ $$ = $1;
+ FREESTACK($2)
+ }
+ | scalarLit
+ {
+ // create a new list and add the literal element
+ $$ = new QtComplexData::QtScalarDataList();
+ $$->push_back($1);
+ };
+
+
+
+
+trimExp: generalExp mintervalExp
+ {
+ QtDomainOperation *dop = new QtDomainOperation( $2 );
+ dop->setInput( $1 ); // e.g. variable name
+ parseQueryTree->removeDynamicObject( $1 );
+ parseQueryTree->removeDynamicObject( $2 );
+ parseQueryTree->addDynamicObject( dop );
+ $$ = dop;
+ if (mflag == MF_IN_CONTEXT)
+ parseQueryTree->addDomainObject( dop );
+ };
+
+marray_head:
+ MARRAY
+ {
+ mflag = MF_IN_CONTEXT;
+ QueryTree::symtab.initScope();
+ }
+ iv
+ {
+ $$ = $3;
+ $$->parseInfo = *($1.info);
+ FREESTACK($1)
+ };
+
+mddExp: marray_head VALUES generalExp
+ {
+ // create a new list and add the element
+ QtMarrayOp2::mddIntervalListType *dlist = new QtMarrayOp2::mddIntervalListType();
+ dlist->push_back(*($1));
+
+ // concatenate intervals and variable names, then do a domain rewrite
+ QtMarrayOp2 *qma = new QtMarrayOp2( dlist, $3 );
+ qma->setOldMarray(true);
+ qma->rewriteVars( );
+
+ char *stra = strdup( $1->variable.c_str() );
+ $$ = new QtMarrayOp( stra, $1->tree, qma->getInput());
+ parseQueryTree->addCString(stra);
+
+ QueryTree::symtab.exitScope();
+ mflag = MF_NO_CONTEXT;
+
+ // release memory
+ while (!(dlist->empty()))
+ {
+ dlist->erase(dlist->begin());
+ }
+ delete dlist;
+ delete qma;
+ delete $1;
+ parseQueryTree->removeDynamicObject( $3 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ }
+ | marray_head COMMA ivList VALUES generalExp
+ {
+ // create a new list and add the element
+ QtMarrayOp2::mddIntervalListType *dlist = new QtMarrayOp2::mddIntervalListType();
+ dlist->push_back(*($1));
+
+ // concatenate the lists
+ dlist->insert(
+ dlist->end(),
+ $3->begin(),
+ $3->end()
+ );
+
+ // concatenate intervals and variable names, then do a domain rewrite
+ QtMarrayOp2 *qma = new QtMarrayOp2( dlist, $5 );
+ qma->setOldMarray(false);
+ qma->rewriteVars( );
+ if (!(qma->concatenateIntervals()))
+ {
+ // TODO: change error code!
+ // save the parse error info and stop the parser
+ if ( parseError )
+ delete parseError;
+ parseError = new ParseInfo( 313, ($1->parseInfo).getToken().c_str(),
+ ($1->parseInfo).getLineNo(),
+ ($1->parseInfo).getColumnNo() );
+ QueryTree::symtab.exitScope();
+ mflag = MF_NO_CONTEXT;
+
+ // release memory
+ while (!(dlist->empty()))
+ {
+ dlist->erase(dlist->begin());
+ }
+ delete dlist;
+ delete qma;
+ delete $1;
+ parseQueryTree->removeDynamicObject( $5 );
+ FREESTACK($2)
+ FREESTACK($4)
+ YYABORT;
+ }
+
+ r_Minterval *dinterval = new r_Minterval(qma->greatDomain);
+ std::string *dvariable = new std::string(qma->greatIterator);
+ parseQueryTree->rewriteDomainObjects(dinterval, dvariable, dlist);
+
+ // initialize old good QtMarray with the translated data
+ QtMintervalData *mddIntervalData = new QtMintervalData(*dinterval);
+ $$ = new QtMarrayOp( dvariable->c_str(), new QtConst(mddIntervalData), qma->getInput());
+// $$->setParseInfo( *($1.info) );
+
+ QueryTree::symtab.exitScope();
+ mflag = MF_NO_CONTEXT;
+
+ // release memory
+ while (!(dlist->empty()))
+ {
+ dlist->erase(dlist->begin());
+ }
+ delete dlist;
+ delete qma;
+ delete $1;
+ parseQueryTree->removeDynamicObject( $5 );
+ parseQueryTree->addDynamicObject( $$ );
+ FREESTACK($2)
+ FREESTACK($4)
+ };
+
+ivList: ivList COMMA iv
+ {
+ // add the element and give back the list
+ $1->push_back(*($3));
+ $$ = $1;
+ delete $3;
+ FREESTACK($2)
+ }
+ | iv
+ {
+ // create a new list and add the element
+ $$ = new QtMarrayOp2::mddIntervalListType();
+ $$->push_back(*($1));
+ delete $1;
+ };
+
+iv: marrayVariable IN generalExp
+ {
+ if (!QueryTree::symtab.putSymbol($1.value, 1)) // instead of 1 put the dimensionality
+ {
+ // save the parse error info and stop the parser
+ if ( parseError )
+ delete parseError;
+ parseError = new ParseInfo( 312, $1.info->getToken().c_str(),
+ $1.info->getLineNo(),
+ $1.info->getColumnNo() );
+ parseQueryTree->removeDynamicObject( $3 );
+ FREESTACK($2)
+ QueryTree::symtab.wipe();
+ YYABORT;
+ }
+ $$ = new QtMarrayOp2::mddIntervalType();
+ $$->variable = $1.value;
+ $$->tree = $3;
+ $$->parseInfo = *($1.info);
+ parseQueryTree->removeDynamicObject( $3 );
+ FREESTACK($2);
+ };
+
+/*--------------------------------------------------------------------
+ * Grammar ends here
+ *--------------------------------------------------------------------
+ */
+%% // C code section
+
+void yyerror( char* /*s*/ ) {
+ if( !parseError ) {
+
+ if( yytext[0] == '\0' ) {
+ // unexpected end of query
+ parseError = new ParseInfo( 308, yytext, lineNo, columnNo - strlen(yytext) );
+ }
+ else {
+ // general parse error
+ parseError = new ParseInfo( 300, yytext, lineNo, columnNo - strlen(yytext) );
+ }
+ }
+}
diff --git a/qlparser/parseinfo.cc b/qlparser/parseinfo.cc
new file mode 100644
index 0000000..d16dad6
--- /dev/null
+++ b/qlparser/parseinfo.cc
@@ -0,0 +1,102 @@
+/*
+* 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, ParseInfo: $Id: parseinfo.cc,v 1.6 2002/06/19 14:36:23 coman Exp $";
+
+#include <iostream>
+using namespace std;
+
+#include "qlparser/parseinfo.hh"
+
+
+ParseInfo::ParseInfo()
+ : errorNo( 0 ),
+ token( "" ),
+ lineNo( 0 ),
+ columnNo( 0 )
+{
+}
+
+ParseInfo::ParseInfo(const ParseInfo& old)
+ : errorNo( 0 ),
+ token( "" ),
+ lineNo( 0 ),
+ columnNo( 0 )
+{
+ errorNo=old.errorNo;
+ lineNo=old.lineNo;
+ columnNo=old.columnNo;
+ token=old.token;
+}
+
+ParseInfo::ParseInfo( const char* initToken, unsigned int initLineNo, unsigned initColumnNo )
+ : errorNo( 0 ),
+ token( "" ),
+ lineNo( initLineNo ),
+ columnNo( initColumnNo )
+{
+ if(initToken) {
+ token=initToken;
+ }
+}
+
+
+
+ParseInfo::ParseInfo( unsigned long initErrorNo, const char* initToken, unsigned int initLineNo, unsigned initColumnNo )
+ : errorNo( initErrorNo ),
+ token( "" ),
+ lineNo( initLineNo ),
+ columnNo( initColumnNo )
+{
+ if(initToken) {
+ token=initToken;
+ }
+}
+
+ParseInfo&
+ParseInfo::operator=(const ParseInfo& old)
+{
+ if(this != &old) {
+ errorNo=old.errorNo;
+ lineNo=old.lineNo;
+ columnNo=old.columnNo;
+ token=old.token;
+ }
+ return *this;
+}
+
+void
+ParseInfo::printStatus( ostream& s ) const
+{
+ s << "Error number: " << errorNo << " Token: " << token.c_str() << " Line: " << lineNo << " Column: " << columnNo << endl;
+}
+
diff --git a/qlparser/parseinfo.hh b/qlparser/parseinfo.hh
new file mode 100644
index 0000000..7097139
--- /dev/null
+++ b/qlparser/parseinfo.hh
@@ -0,0 +1,111 @@
+/*
+* 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>.
+*/
+#ifndef _PARSEINFO_
+#define _PARSEINFO_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ This class holds some information about a token and its
+ location in the parse string. Additionally, it can keep
+ an error number which is used in the query tree to report
+ error with some context information within the query string.
+
+*/
+
+class ParseInfo
+{
+ public:
+
+ /// default constructor
+ ParseInfo();
+
+ /// constructor getting error number, token and location information
+ ParseInfo( unsigned long errorNo, const char* token, unsigned int lineNo, unsigned columnNo );
+
+ /// copy constructor
+ ParseInfo( const ParseInfo& old);
+
+ /// constructor getting token and location information
+ ParseInfo( const char* token, unsigned int lineNo, unsigned columnNo );
+
+ //@Man: Read/Write methods
+ //@{
+ ///
+ inline unsigned long getErrorNo() const;
+ ///
+ inline const std::string& getToken() const;
+ ///
+ inline unsigned int getLineNo() const;
+ ///
+ inline unsigned int getColumnNo() const;
+ ///
+ inline void setErrorNo( unsigned long errorNo );
+ ///
+ inline void setToken( const std::string& text );
+ ///
+ inline void setToken( const char* text );
+ ///
+ inline void setLineNo( unsigned int lineNo );
+ ///
+ inline void setColumnNo( unsigned int columnNo );
+ ///
+ //@}
+
+ void printStatus( std::ostream& s= std::cout ) const;
+
+ ParseInfo& operator=(const ParseInfo& old);
+
+ private:
+ //@Man: Attributes
+ //@{
+ ///
+ unsigned long errorNo;
+ ///
+ unsigned int lineNo;
+ ///
+ unsigned int columnNo;
+ ///
+ std::string token;
+ ///
+ //@}
+};
+
+#include "parseinfo.icc"
+
+#endif
diff --git a/qlparser/parseinfo.icc b/qlparser/parseinfo.icc
new file mode 100644
index 0000000..91e2dd0
--- /dev/null
+++ b/qlparser/parseinfo.icc
@@ -0,0 +1,100 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline
+unsigned long
+ParseInfo::getErrorNo() const
+{
+ return errorNo;
+}
+
+
+
+inline const std::string&
+ParseInfo::getToken() const
+{
+ return token;
+}
+
+
+
+inline
+unsigned int
+ParseInfo::getLineNo() const
+{
+ return lineNo;
+}
+
+
+
+inline unsigned int
+ParseInfo::getColumnNo() const
+{
+ return columnNo;
+}
+
+
+
+inline void
+ParseInfo::setErrorNo( unsigned long newNo )
+{
+ errorNo = newNo;
+}
+
+
+
+inline void
+ParseInfo::setToken( const std::string& text )
+{
+ token = text;
+}
+
+
+
+inline void
+ParseInfo::setToken( const char* text )
+{
+ token = std::string(text);
+}
+
+
+
+inline void
+ParseInfo::setLineNo( unsigned int newNo )
+{
+ lineNo = newNo;
+}
+
+
+
+inline void
+ParseInfo::setColumnNo( unsigned int newNo )
+{
+ columnNo = newNo;
+}
diff --git a/qlparser/qtatomicdata.cc b/qlparser/qtatomicdata.cc
new file mode 100644
index 0000000..a8b12f8
--- /dev/null
+++ b/qlparser/qtatomicdata.cc
@@ -0,0 +1,212 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, QtAtomicData: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtatomicdata.cc,v 1.18 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtatomicdata.hh"
+#include "relcatalogif/basetype.hh"
+#include "relcatalogif/alltypes.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+#include <iostream>
+
+#include "raslib/rmdebug.hh"
+
+
+QtAtomicData::QtAtomicData()
+ : QtScalarData()
+{
+}
+
+
+
+QtAtomicData::QtAtomicData( r_Long value, unsigned short byteLength )
+ : QtScalarData()
+{
+ switch( byteLength )
+ {
+ case 1: valueType = TypeFactory::mapType("Octet"); break;
+ case 2: valueType = TypeFactory::mapType("Short"); break;
+ case 4: valueType = TypeFactory::mapType("Long"); break;
+
+ default:
+ RMInit::logOut << "Error: QtAtomicData::QtAtomicData() - signed integer value with length "
+ << byteLength << " is not supported." << endl;
+ }
+
+ if( valueType )
+ {
+ r_Long temp = value;
+ valueBuffer = new char[ valueType->getSize() ];
+ valueType->makeFromCLong( valueBuffer, &temp );
+ }
+}
+
+
+QtAtomicData::QtAtomicData( r_ULong value, unsigned short byteLength )
+ : QtScalarData()
+{
+ switch( byteLength )
+ {
+ case 1: valueType = TypeFactory::mapType("Char"); break;
+ case 2: valueType = TypeFactory::mapType("UShort"); break;
+ case 4: valueType = TypeFactory::mapType("ULong"); break;
+
+ default:
+ RMInit::logOut << "Error: QtAtomicData::QtAtomicData() - unsigned integer value with length "
+ << byteLength << " is not supported." << endl;
+ }
+
+
+ if( valueType )
+ {
+ r_ULong temp = value;
+ valueBuffer = new char[ valueType->getSize() ];
+ valueType->makeFromCULong( valueBuffer, &temp );
+ }
+}
+
+
+
+QtAtomicData::QtAtomicData( bool value )
+ : QtScalarData()
+{
+ r_ULong valueULong = (r_ULong)value;
+
+ valueType = TypeFactory::mapType("Bool");
+ valueBuffer = new char[ valueType->getSize() ];
+ valueType->makeFromCULong( valueBuffer, &valueULong );
+}
+
+
+
+QtAtomicData::QtAtomicData( double value, unsigned short byteLength )
+ : QtScalarData()
+{
+ switch( byteLength )
+ {
+ case 4: valueType = TypeFactory::mapType("Float"); break;
+ case 8: valueType = TypeFactory::mapType("Double"); break;
+
+ default:
+ RMInit::logOut << "Error: QtAtomicData::QtAtomicData() - float value with length "
+ << byteLength << " is not supported." << endl;
+ }
+
+
+ if( valueType )
+ {
+ valueBuffer = new char[ valueType->getSize() ];
+ valueType->makeFromCDouble( valueBuffer, &value );
+ }
+}
+
+
+
+
+QtAtomicData::QtAtomicData( const QtAtomicData& obj )
+ : QtScalarData( obj )
+{
+}
+
+QtAtomicData::~QtAtomicData()
+{
+}
+
+r_ULong
+QtAtomicData::getUnsignedValue() const
+{
+ r_ULong value=0;
+
+ if( valueType )
+ valueType->convertToCULong( valueBuffer, &value );
+
+ return value;
+}
+
+
+
+r_Long
+QtAtomicData::getSignedValue() const
+{
+ r_Long value=0;
+
+ if( valueType )
+ valueType->convertToCLong( valueBuffer, &value );
+
+ return value;
+}
+
+
+
+double
+QtAtomicData::getDoubleValue() const
+{
+ double value=0;
+
+ if( valueType )
+ valueType->convertToCDouble( valueBuffer, &value );
+
+ return value;
+}
+
+
+
+void
+QtAtomicData::printStatus( ostream& stream ) const
+{
+ stream << "atomic, " << flush;
+
+ QtScalarData::printStatus( stream );
+}
+
+
+// for complex types
+QtAtomicData::QtAtomicData(double valRe, double valIm, unsigned short size)
+: QtScalarData() {
+ double dummyRe = valRe;
+ double dummyIm = valIm;
+
+ if(size == 2 * sizeof(float))
+ valueType = TypeFactory::mapType("Complex1");
+ else
+ valueType = TypeFactory::mapType("Complex2");
+
+ valueBuffer = new char[valueType->getSize()];
+ valueType->makeFromCDouble(valueBuffer + ((GenericComplexType *)valueType)->getReOffset(), &dummyRe);
+ valueType->makeFromCDouble(valueBuffer + ((GenericComplexType *)valueType)->getImOffset(), &dummyIm);
+}
+
diff --git a/qlparser/qtatomicdata.hh b/qlparser/qtatomicdata.hh
new file mode 100644
index 0000000..769744d
--- /dev/null
+++ b/qlparser/qtatomicdata.hh
@@ -0,0 +1,134 @@
+/*
+* 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>.
+*/
+#ifndef _QTATOMICDATA_HH_
+#define _QTATOMICDATA_HH_
+
+#include "qlparser/qtscalardata.hh"
+#include "raslib/odmgtypes.hh"
+
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents an atomic value handled by the query tree.
+
+*/
+
+class QtAtomicData : public QtScalarData
+{
+ public:
+ /// default constructor
+ QtAtomicData();
+
+ /// constructor getting signed integer data
+ QtAtomicData( r_Long value, unsigned short byteLength );
+ /**
+ The value for {\tt byteLength} specifies the type of the constant.
+
+ \begin{tabular}{lll}
+ 1 && OCTET\\
+ 2 && SHORT\\
+ 4 && LONG\\
+ \end{tabular}
+ */
+
+ /// constructor getting unsigned integer data
+ QtAtomicData( r_ULong value, unsigned short byteLength );
+ /**
+ The value for {\tt byteLength} specifies the type of the constant.
+
+ \begin{tabular}{lll}
+ 1 && CHAR\\
+ 2 && USHORT\\
+ 4 && ULONG\\
+ \end{tabular}
+ */
+
+ /// constructor getting boolean data
+ QtAtomicData( bool value );
+
+ /// constructor getting float data
+ QtAtomicData( double value, unsigned short byteLength );
+ /**
+ The value for {\tt byteLength} specifies the type of the constant.
+
+ \begin{tabular}{lll}
+ 4 && FLOAT\\
+ 8 && DOUBLE\\
+ \end{tabular}
+ */
+
+ /// constructor getting complex data
+ QtAtomicData(double valRe, double valIm, unsigned short size);
+
+ /// copy constructor
+ QtAtomicData( const QtAtomicData& obj );
+
+ /// destructor
+ virtual ~QtAtomicData();
+
+ /// returning unsigned value of an unsigned atomic type if it is one, 0 otherwise
+ r_ULong getUnsignedValue() const;
+
+ /// returning signed value of a signed atomic type if it is one, 0 otherwise
+ r_Long getSignedValue() const;
+
+ /// returning double value if it is one, 0 otherwise
+ double getDoubleValue() const;
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+};
+
+#include "qlparser/qtatomicdata.icc"
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtatomicdata.icc b/qlparser/qtatomicdata.icc
new file mode 100644
index 0000000..2651f9c
--- /dev/null
+++ b/qlparser/qtatomicdata.icc
@@ -0,0 +1,29 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
diff --git a/qlparser/qtbinaryfunc.cc b/qlparser/qtbinaryfunc.cc
new file mode 100644
index 0000000..9b77888
--- /dev/null
+++ b/qlparser/qtbinaryfunc.cc
@@ -0,0 +1,1174 @@
+/*
+* 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:
+ * - QtScale is expected to have rounding errors with >1 tiles
+ * - shift, extend, scale release input tiles only at end; this
+ * shouldbe optimized (release immediately after evaluating)
+ * - why is this file called "binary"? all ops have just one MDD!
+ * - QtShift(), QtExtend() deliver for >1 tiles under PG an error
+ * "libpq 'select' did not yield 1 result but 0"
+ * which however does not seem to affect the result.
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, QtMintervalSelect, QtShift: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtbinaryfunc.cc,v 1.37 2005/09/03 20:17:55 rasdev Exp $";
+
+#include "mymalloc/mymalloc.h"
+
+#include "mymalloc/mymalloc.h"
+
+#include "qlparser/qtbinaryfunc.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtintervaldata.hh"
+#include "qlparser/qtmintervaldata.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtpointdata.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "tilemgr/tile.hh"
+
+#include "raslib/rmdebug.hh"
+#include "raslib/dlist.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+
+// --- QtShift --------------------------------------------------
+
+const QtNode::QtNodeType QtShift::nodeType = QT_SHIFT;
+
+QtShift::QtShift( QtOperation* mddOp, QtOperation* pointOp )
+ : QtBinaryOperation( mddOp, pointOp )
+{
+}
+
+
+
+bool
+QtShift::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+QtData*
+QtShift::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtShift", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand1 = NULL;
+ QtData* operand2 = NULL;
+
+ // evaluate sub-nodes to obtain operand values
+ if( getOperands( inputList, operand1, operand2 ) )
+ {
+ //
+ // This implementation simply creates a new transient MDD object with the new
+ // domain while copying the data. Optimization of this is left for future work.
+ //
+
+ QtMDD* qtMDDObj = (QtMDD*)operand1;
+ const r_Point& transPoint = ((QtPointData*)operand2)->getPointData();
+ MDDObj* currentMDDObj = qtMDDObj->getMDDObject();
+
+ if( transPoint.dimension() != qtMDDObj->getLoadDomain().dimension() )
+ {
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ RMInit::logOut << "Error: QtShift::evaluate( QtDataList* ) - dimensionality of MDD and point expression do not match." << endl;
+ parseInfo.setErrorNo(407);
+ throw parseInfo;
+ }
+
+ // compute new domain
+ r_Minterval destinationDomain( qtMDDObj->getLoadDomain().create_translation( transPoint ) );
+
+ // create a transient MDD object for the query result
+ MDDObj* resultMDD = new MDDObj( currentMDDObj->getMDDBaseType(), destinationDomain );
+
+ // get all tiles
+ vector<Tile* >* tiles = currentMDDObj->intersect( qtMDDObj->getLoadDomain() );
+
+ // iterate over source tiles
+ for( vector<Tile*>::iterator tileIter = tiles->begin(); tileIter != tiles->end(); tileIter++ )
+ {
+ // get relevant area of source tile
+ r_Minterval sourceTileDomain = qtMDDObj->getLoadDomain().create_intersection( (*tileIter)->getDomain() );
+
+ // compute translated tile domain
+ r_Minterval destinationTileDomain = sourceTileDomain.create_translation( transPoint );
+
+ // create a new transient tile, copy the transient data, and insert it into the mdd object
+ // FIXME: how can this work without tile area allocation??? -- PB 2005-jun-19
+ Tile* newTransTile = new Tile( destinationTileDomain, currentMDDObj->getCellType() );
+ newTransTile->copyTile( destinationTileDomain, *tileIter, sourceTileDomain );
+ resultMDD->insertTile( newTransTile );
+ }
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)resultMDD );
+
+ // delete the tile vector, the tiles itself are deleted when the destructor
+ // of the MDD object is called
+ delete tiles;
+ tiles=NULL;
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtShift::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtShift Object " << getNodeType() << endl;
+
+ QtBinaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtShift::printAlgebraicExpression( ostream& s )
+{
+ s << "shift(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ",";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+void
+QtShift::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtShift", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtNode::QtTrimList *list1=NULL, *list2=NULL;
+
+ if( input1 && input2 )
+ {
+ QtNode::QtTrimList::iterator iter;
+
+ //
+ // The result of input2 has to be a constant expression.
+ //
+
+ // shift of trimList is just possible, if no open bounds are available
+ bool openBounds = false;
+ for( iter=trimList->begin(); iter!=trimList->end() && !openBounds; iter++ )
+ openBounds = !((*iter)->interval.is_low_fixed()) || !((*iter)->interval.is_high_fixed());
+
+ if( openBounds )
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ RMInit::logOut << "Error: QtShift::optimizeLoad() - spatial domain shift of open bounds is not supported" << endl;
+ parseInfo.setErrorNo(409);
+ throw parseInfo;
+ }
+
+ QtData* operand = input2->evaluate(NULL);
+
+ if( !operand )
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ RMInit::logOut << "Error: QtShift::optimizeLoad() - second operand of shift function must be a constant expression." << endl;
+ parseInfo.setErrorNo(408);
+ throw parseInfo;
+ }
+
+ if( operand->getDataType() != QT_POINT )
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ operand->deleteRef();
+
+ RMInit::logOut << "Error: QtShift::optimizeLoad() - second operand must be of type Point." << endl;
+ parseInfo.setErrorNo(406);
+ throw parseInfo;
+ }
+
+ // get transPoint
+ const r_Point& transPoint = ((QtPointData*)operand)->getPointData();
+
+ // shift trim elements by -transPoint
+ for( iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ QtTrimElement* elem = *iter;
+
+ if( elem->dimension <= transPoint.dimension() )
+ elem->interval.set_interval( elem->interval.low() - transPoint[elem->dimension], elem->interval.high() - transPoint[elem->dimension] );
+ }
+
+ // point is not needed anymore
+ operand->deleteRef();
+
+ input1->optimizeLoad( trimList );
+ }
+ else
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+ }
+}
+
+
+
+const QtTypeElement&
+QtShift::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtShift", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input1 && input2 )
+ {
+
+ // get input types
+ const QtTypeElement& inputType1 = input1->checkType( typeTuple );
+ const QtTypeElement& inputType2 = input2->checkType( typeTuple );
+
+ if( inputType1.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtShift::checkType() - first operand must be of type MDD." << endl;
+ parseInfo.setErrorNo(405);
+ throw parseInfo;
+ }
+
+ if( inputType2.getDataType() != QT_POINT )
+ {
+ RMInit::logOut << "Error: QtShift::checkType() - second operand must be of type Point." << endl;
+ parseInfo.setErrorNo(406);
+ throw parseInfo;
+ }
+
+ // pass MDD type
+ dataStreamType = inputType1;
+ }
+ else
+ RMInit::logOut << "Error: QtShift::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
+// --- QtExtend --------------------------------------------------
+
+const QtNode::QtNodeType QtExtend::nodeType = QT_EXTEND;
+
+QtExtend::QtExtend( QtOperation* mddOp, QtOperation* mintervalOp )
+ : QtBinaryOperation( mddOp, mintervalOp )
+{
+}
+
+
+
+bool
+QtExtend::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+QtData*
+QtExtend::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtExtend", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL; // operation result
+ QtData* operand1 = NULL; // 1st operand: MDD expression
+ QtData* operand2 = NULL; // 2nd operand: Minterval expression
+ vector<Tile*> completeAreaList; // list of tiles comprising the whole area (possibly with holes); needed for 1-code below
+
+ if( getOperands( inputList, operand1, operand2 ) )
+ {
+ //
+ // This implementation simply creates a single new transient MDD object with the new
+ // domain while copying the data.
+ // FIXME: create a tiled object
+ //
+
+ QtMDD* qtMDDObj = (QtMDD*)operand1; // object to be extended
+ r_Minterval targetDomain = ((QtMintervalData*)operand2)->getMintervalData(); // new domain of extended object
+ MDDObj* currentMDDObj = qtMDDObj->getMDDObject();
+
+ // precondition checks (we call the MDD C and the Minterval M):
+ // - dim(C) == dim(M)
+ if( targetDomain.dimension() != qtMDDObj->getLoadDomain().dimension() )
+ {
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ RMInit::logOut << "Error: QtExtend::evaluate( QtDataList* ) - dimensionality of MDD and point expression do not match." << endl;
+ parseInfo.setErrorNo(407);
+ throw parseInfo;
+ }
+
+ // - M does not contain open bounds (i.e., "*")
+ if( ! targetDomain.is_origin_fixed() || ! targetDomain.is_high_fixed() )
+ {
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ RMInit::logOut << "Error: QtExtend::evaluate( QtDataList* ) - target domain must not have open bounds." << endl;
+ parseInfo.setErrorNo(420);
+ throw parseInfo;
+ }
+ // - M.subset( sdom(C) ); can we relieve this?
+ if( ! targetDomain.covers( qtMDDObj->getLoadDomain() ) )
+ {
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ RMInit::logOut << "Error: QtExtend::evaluate( QtDataList* ) - new interval does not cover MDD to be extended." << endl;
+ parseInfo.setErrorNo(421);
+ throw parseInfo;
+ }
+
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ) - extending MDD with basetype " << currentMDDObj->getMDDBaseType() << " and load domain " << qtMDDObj->getLoadDomain() << " to domain " << targetDomain << endl;
+
+ // create a transient MDD object for the query result
+ MDDObj* resultMDD = new MDDObj( currentMDDObj->getMDDBaseType(), targetDomain );
+
+ // --- 1: put all existing tiles into their place ------------------------
+
+ // get all tiles
+ vector<Tile* >* tiles = currentMDDObj->intersect( qtMDDObj->getLoadDomain() );
+
+ // iterate over source tiles
+ // Note that source and target MDD have the same coordinate basis
+ for( vector<Tile*>::iterator tileIter = tiles->begin(); tileIter != tiles->end(); tileIter++ )
+ {
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ) - load domain is " << qtMDDObj->getLoadDomain() << endl;
+ // get relevant area of source tile
+ r_Minterval sourceTileDomain = qtMDDObj->getLoadDomain().create_intersection( (*tileIter)->getDomain() );
+
+ Tile* newTransTile = new Tile( sourceTileDomain, currentMDDObj->getCellType() );
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ) - adding source part " << sourceTileDomain << " of tile " << (*tileIter)->getDomain() << endl;
+ newTransTile->copyTile( sourceTileDomain, *tileIter, sourceTileDomain );
+
+ resultMDD->insertTile( newTransTile ); // needed for 2-code below
+ // completeAreaList.push_back( newTransTile ); // needed for 1-code below
+ }
+
+ // --- 2: fill up new space with null values -----------------------------
+
+#if 0 // this 1-code does the same thing as the 2-code, but easier & more efficiently -- PB 2005-jun-24
+ // INCOMPLETE!
+ // create minimal (1x1) tiles at origin and high end, but only if the source domain isn't there
+ if (targetDomain.get_origin() != qtMDDObj->getLoadDomain().get_origin())
+ {
+ RMInit::logOut << "QtExtend::evaluate( QtDataList* ) - adding aux tile at origin." << endl;
+-> Tile* originTile = new Tile( origin..origin+1 , currentMDDObj->getCellType() );
+ extendDomainList.push_back( originTile );
+ }
+ if (targetDomain.get_high() != qtMDDObj->getLoadDomain().get_high())
+ {
+ RMInit::logOut << "QtExtend::evaluate( QtDataList* ) - adding aux tile at high." << endl;
+-> Tile* highTile = new Tile( high-1..high, currentMDDObj->getCellType() );
+ extendDomainList.push_back( highTile );
+ }
+
+ // merge all tiles into one & free not-used-any-longer stuff
+ Tile* completeTile = new Tile( extendDomainList );
+ delete[] extendDomainList;
+ resultMDD->insertTile( completeTile );
+ delete completeTile;
+
+#else // 2-code; unused -- PB 2005-jun-24
+ // the part below does the trick explicitly, leading to a larger number of result tiles.
+ // establish list of domains
+ vector<r_Minterval> extendDomainList;
+
+ // inspect 2*d lower/upper neighbours
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ): - inspect 2*d lower/upper neighbours, dimension is " << targetDomain.dimension() << endl;
+ for (r_Dimension d=0; d<targetDomain.dimension(); d++)
+ {
+ // is there any space left of original MDD; ie, has MDD been extended left?
+ if (targetDomain.get_origin()[d] < qtMDDObj->getLoadDomain().get_origin()[d])
+ {
+ // this domain is identical to original MDD except for dim d where it is left of original
+ r_Minterval lowerNeighbour = qtMDDObj->getLoadDomain();
+ lowerNeighbour[d] = r_Sinterval( targetDomain.get_origin()[d], qtMDDObj->getLoadDomain().get_origin()[d]-1 );
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ): adding lower neighbour domain " << lowerNeighbour << endl;
+ extendDomainList.push_back( lowerNeighbour );
+ }
+ // is there any space right of original MDD; ie, has MDD been extended right?
+ if (targetDomain.get_high()[d] > qtMDDObj->getLoadDomain().get_high()[d])
+ {
+ // this domain is identical to original MDD except for dim d where it is right of original
+ r_Minterval upperNeighbour = qtMDDObj->getLoadDomain();
+ upperNeighbour[d] =r_Sinterval( qtMDDObj->getLoadDomain().get_high()[d]+1, targetDomain.get_high()[d] );
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ): adding upper neighbour domain " << upperNeighbour << endl;
+ extendDomainList.push_back( upperNeighbour );
+ }
+ }
+
+ // inspect 2^d corner points
+
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ): - inspect 2^d corner neighbours, dimension is " << targetDomain.dimension() << endl;
+ r_Minterval cornerBoxDomain = r_Minterval( targetDomain.dimension() );
+ QtExtend::extendGetCornerTiles( targetDomain, qtMDDObj->getLoadDomain(), 0, targetDomain.dimension(), cornerBoxDomain, &extendDomainList );
+
+ // merge where possible to minimize tile number
+ // ...just an optimization, tbd later
+
+ // create tiles for all domains found
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ): - creating " << extendDomainList.size() << " tiles..." << endl;
+ for( vector<r_Minterval>::iterator domainIter = extendDomainList.begin(); domainIter != extendDomainList.end(); domainIter++ )
+ {
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ): creating tile for domain " << (*domainIter) << endl;
+ Tile* newTransTile = new Tile( *domainIter, currentMDDObj->getCellType() );
+ resultMDD->insertTile( newTransTile );
+ }
+#endif 0
+
+ // --- 3: package into MDD object & finalize -----------------------------
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)resultMDD );
+
+ // delete the tile vector, the tiles itself are deleted when the destructor
+ // of the MDD object is called
+
+ delete tiles;
+ tiles=NULL;
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ // temporary: dump result tile
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ) - result tile = " << newTransTile->printStatus() << endl;
+ // newTransTile->printStatus(99,RMInit::logOut);
+ }
+
+ // RMInit::logOut << "QtExtend::evaluate( QtDataList* ) - done." << endl;
+ return returnValue;
+}
+
+#if 1 // needed for 1-code above -- PB 2005-jun-24
+/**
+aux function for QtExtend::evaluate(): build up (recursing the dimension) a list of all spatial domains that sit in the corners between outerDomain and innerDomain; at the recursion bottom the resulting domain is added to the cornerList.
+**/
+
+void
+QtExtend::extendGetCornerTiles( r_Minterval outerDomain, r_Minterval innerDomain, const r_Dimension currentDim, const r_Dimension maxDim, r_Minterval currentInterval, vector<r_Minterval>* cornerList )
+{
+ // RMInit::logOut << "QtExtend::extendGetCornerTiles( " << outerDomain << ", " << innerDomain << ", " << currentDim << ", " << maxDim << ", " << currentInterval << ", _ ) start" << endl;
+
+ // not yet addressed all dimensions in the current coordinate?
+// note: what about 1D? 0D?
+ if (currentDim < maxDim)
+ {
+ // add domain's lower end, continue building up the minterval
+ // ...but only if the area is nonempty
+ if (outerDomain.get_origin()[currentDim] < innerDomain.get_origin()[currentDim])
+ {
+ // make local working copy
+ r_Minterval extendedInterval( currentInterval );
+ // add i-th coordinate to domain, up to (but excluding) innerDomain
+ extendedInterval[currentDim] = r_Sinterval( outerDomain.get_origin()[currentDim], innerDomain.get_origin()[currentDim]-1 );
+ // inspect next dimension
+ // RMInit::logOut << "QtExtend::extendGetCornerTiles(): recursing for lower end box in next dimension " << currentDim+1 << " using extendedInterval " << extendedInterval << endl;
+ extendGetCornerTiles( outerDomain, innerDomain, currentDim+1, maxDim, extendedInterval, cornerList );
+ }
+ // add domain's upper end, continue building up the minterval
+ if (innerDomain.get_high()[currentDim] < outerDomain.get_high()[currentDim])
+ {
+ // make local working copy
+ r_Minterval extendedInterval( currentInterval );
+ // add i-th coordinate to domain, starting from (but excluding) innerDomain
+ extendedInterval[currentDim] = r_Sinterval( innerDomain.get_high()[currentDim]+1, outerDomain.get_high()[currentDim] );
+ // inspect next dimension
+ // RMInit::logOut << "QtExtend::extendGetCornerTiles(): recursing for upper end box in next dimension " << currentDim+1 << " using extendedInterval " << extendedInterval << endl;
+ extendGetCornerTiles( outerDomain, innerDomain, currentDim+1, maxDim, extendedInterval, cornerList );
+ }
+ }
+ else if (currentDim > maxDim)
+ {
+ // this is an error, see preconditions
+ RMInit::logOut << "QtExtend::extendGetCornerTiles(): error: dimension overflow." << endl;
+ }
+ else // then we've reached currentDim==maxDim
+ {
+ // add this minterval to the tile domain list
+ cornerList->push_back( currentInterval );
+ // RMInit::logOut << "QtExtend::extendGetCornerTiles(): added " << currentInterval << " to tile domain list." << endl;
+ }
+
+ // RMInit::logOut << "QtExtend::extendGetCornerTiles() done." << endl;
+}
+#endif 1
+
+void
+QtExtend::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtExtend Object " << getNodeType() << endl;
+
+ QtBinaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtExtend::printAlgebraicExpression( ostream& s )
+{
+ s << "extend(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ",";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+void
+QtExtend::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtExtend", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtNode::QtTrimList *list1=NULL, *list2=NULL;
+
+ if( input1 && input2 )
+ {
+#if 0 // not yet sure what to do -- PB 2005-06-18
+
+ QtNode::QtTrimList::iterator iter;
+
+ //
+ // The result of input2 has to be a constant expression.
+ //
+
+ // shift of trimList is just possible, if no open bounds are available
+ bool openBounds = false;
+ for( iter=trimList->begin(); iter!=trimList->end() && !openBounds; iter++ )
+ openBounds = !((*iter)->interval.is_low_fixed()) || !((*iter)->interval.is_high_fixed());
+
+ if( openBounds )
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ RMInit::logOut << "Error: QtExtend::optimizeLoad() - spatial domain shift of open bounds is not supported" << endl;
+// XXX need new error code
+ parseInfo.setErrorNo(409);
+ throw parseInfo;
+ }
+
+ QtData* operand = input2->evaluate(NULL);
+
+ if( !operand )
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ RMInit::logOut << "Error: QtExtend::optimizeLoad() - second operand of extend function must be a constant expression." << endl;
+// XXX correct new error code
+ parseInfo.setErrorNo(408);
+ throw parseInfo;
+ }
+
+ if( operand->getDataType() != QT_MINTERVAL )
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ operand->deleteRef();
+
+ RMInit::logOut << "Error: QtExtend::optimizeLoad() - second operand must be of type Minterval." << endl;
+// XXX correct new error code
+ parseInfo.setErrorNo(406);
+ throw parseInfo;
+ }
+
+ // get extend target domain
+ const r_Minterval& targetDomain = ((QtPointData*)operand)->getMintervalData();
+
+ // shift trim elements by -transPoint
+ // XXX replace with extend() code
+ for( iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ QtTrimElement* elem = *iter;
+
+ if( elem->dimension <= transPoint.dimension() )
+ elem->interval.set_interval( elem->interval.low() - transPoint[elem->dimension], elem->interval.high() - transPoint[elem->dimension] );
+ }
+
+ // point is not needed anymore
+ operand->deleteRef();
+#endif 0 // not yet sure what to do -- PB 2005-06-18
+
+ input1->optimizeLoad( trimList );
+ }
+ else
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+ }
+}
+
+
+
+const QtTypeElement&
+QtExtend::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtExtend", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input1 && input2 )
+ {
+
+ // get input types
+ const QtTypeElement& inputType1 = input1->checkType( typeTuple );
+ const QtTypeElement& inputType2 = input2->checkType( typeTuple );
+
+ if( inputType1.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtExtend::checkType() - first operand must be of type MDD." << endl;
+ parseInfo.setErrorNo(405);
+ throw parseInfo;
+ }
+
+ if( inputType2.getDataType() != QT_MINTERVAL )
+ {
+ RMInit::logOut << "Error: QtExtend::checkType() - second operand must be of type Minterval." << endl;
+ parseInfo.setErrorNo(422);
+ throw parseInfo;
+ }
+
+ // pass MDD type
+ dataStreamType = inputType1;
+ }
+ else
+ RMInit::logOut << "Error: QtExtend::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
+
+// --- QtScale --------------------------------------------------
+
+const QtNode::QtNodeType QtScale::nodeType = QT_SCALE;
+
+QtScale::QtScale( QtOperation* mddOp, QtOperation* pointOp )
+ : QtBinaryOperation( mddOp, pointOp )
+{
+}
+
+
+
+bool
+QtScale::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+#include <iomanip>
+#include <math.h>
+
+// this define was used during testing, we had a problem
+inline double FLOOR(double a) {
+ return floor(a);
+}
+
+QtData*
+QtScale::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtScale", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand1 = NULL;
+ QtData* operand2 = NULL;
+
+ if(!getOperands( inputList, operand1, operand2 ) )
+ return returnValue;
+
+ QtMDD* qtMDDObj = (QtMDD*)operand1;
+ MDDObj* currentMDDObj = qtMDDObj->getMDDObject();
+ vector<r_Double> scaleVector(0);
+
+ scaleVector = vector<r_Double>( qtMDDObj->getLoadDomain().dimension() );
+
+ r_Minterval sourceDomain = qtMDDObj->getLoadDomain();
+ r_Minterval targetDomain;
+ r_Point origin1 = sourceDomain.get_origin();
+ r_Point origin2 = qtMDDObj->getMDDObject()->getCurrentDomain().get_origin();
+
+ r_Minterval wishedTargetDomain;
+ r_Point translation;
+
+ //used for scale with wishedIv
+ bool isWishedTargetSet = false;
+ r_Double sourceRange=0., targetRange=0., f=0., Tl=0., Th=0.;
+
+ switch( operand2->getDataType() )
+ {
+ case QT_POINT:
+ {
+ const r_Point& transPoint = ((QtPointData*)operand2)->getPointData();
+
+ if( transPoint.dimension() != qtMDDObj->getLoadDomain().dimension() )
+ {
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ RMInit::logOut << "Error: QtScale::evaluate( QtDataList* ) - dimensionalities of MDD and scale expression are not matching." << endl;
+ parseInfo.setErrorNo(418);
+ throw parseInfo;
+ }
+
+ for( int i=0; i<scaleVector.size(); i++ )
+ scaleVector[i] = transPoint[i];
+ }
+ break;
+
+ case QT_CHAR:
+ case QT_USHORT:
+ case QT_ULONG:
+ {
+ for( int i=0; i<scaleVector.size(); i++ )
+ scaleVector[i] = ((QtAtomicData*)operand2)->getUnsignedValue();;
+ }
+ break;
+
+ case QT_OCTET:
+ case QT_SHORT:
+ case QT_LONG:
+ {
+ for( int i=0; i<scaleVector.size(); i++ )
+ scaleVector[i] = ((QtAtomicData*)operand2)->getSignedValue();;
+ }
+ break;
+
+ case QT_DOUBLE:
+ case QT_FLOAT:
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtScale", "Scaling: " << ((QtAtomicData*)operand2)->getDoubleValue() )
+ for( int i=0; i<scaleVector.size(); i++ )
+ scaleVector[i] = ((QtAtomicData*)operand2)->getDoubleValue();
+ }
+ break;
+
+ case QT_MINTERVAL:
+ {
+ wishedTargetDomain = ((QtMintervalData*)operand2)->getMintervalData();
+ isWishedTargetSet=true;
+
+ if( wishedTargetDomain.dimension() != sourceDomain.dimension())
+ {
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ RMInit::logOut << "Error: QtScale::evaluate( QtDataList* ) - dimensionalities of MDD and scale expression are not matching." << endl;
+ parseInfo.setErrorNo(418);
+ throw parseInfo;
+ }
+
+ for( int i=0; i<scaleVector.size(); i++ )
+ {
+ sourceRange = (r_Double)sourceDomain[i].get_extent();
+ targetRange = (r_Double)wishedTargetDomain[i].get_extent();
+
+ if(sourceRange != 0.)
+ {
+ scaleVector[i] = targetRange / sourceRange;
+ f = scaleVector[i];
+
+ Tl = FLOOR(f*sourceDomain[i].low());
+ //correction by 1e-6 to avoid the strage bug when Th was a
+ //integer value and floor return value-1(e.g. query 47.ql)
+ Th = FLOOR(f*(sourceDomain[i].high()+1) + 0.000001)-1;
+
+// FIXME BUG if(Tl != Th)
+// Th--;
+
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtScale", "Scale: before f="<<setprecision(12)<<f)
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtScale", "Scale: " << endl
+ <<"precalculated: "<<Tl<<':'<<Th<<"<-->"<<wishedTargetDomain[i].low()<<':'<<wishedTargetDomain[i].high()<<endl
+ <<"pro memoria: "<<(r_Range)(f*(sourceDomain[i].high()+1))<<", "<<(f*(sourceDomain[i].high()+1))
+ <<", "<<floor(f*(sourceDomain[i].high()+1))
+ <<", "<<ceil(f*(sourceDomain[i].high()+1)))
+
+ if( (Th-Tl+1) != targetRange )
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtScale", "Scale: correction necessary: "<<Tl<<':'<<Th<<"<-->"<<wishedTargetDomain[i].low()<<':'<<wishedTargetDomain[i].high())
+
+ f = f + (targetRange - (Th-Tl+1))/sourceRange;
+
+ // cout<<"f="<<setprecision(12)<<f<<" scale[i]="<<setprecision(12)<<scaleVector[i]<<endl;
+
+ Tl = FLOOR(f*sourceDomain[i].low());
+ //correction by 1e-6 to avoid the strage bug when Th was a
+ //integer value and floor return value-1(e.g. query 47.ql)
+ Th = FLOOR(f*(sourceDomain[i].high()+1) + 0.000001)-1;
+// FIXME BUG if(Tl != Th)
+// Th--;
+
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtScale", "Scale: ->: "<<Tl<<':'<<Th<<"<-->"<<wishedTargetDomain[i].low()<<':'<<wishedTargetDomain[i].high())
+
+ scaleVector[i]=f;
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtScale", "Scale: after f="<<setprecision(12)<<f)
+ }
+ }
+ else
+ {
+ scaleVector[i] =0; //exception? it can't heapen, this error is filtered long before reaching this point
+ }
+ }
+ }
+ break;
+ default:
+ RMDBGONCE(0, RMDebug::module_qlparser, "r_QtScale", "evaluate() bad type operand2" << operand2->getDataType());
+ break;
+ }
+
+// ----------------------------------------------------------
+
+#ifdef RMANDEBUG
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtScale", "Scale vector : " )
+ for( int i=0; i<scaleVector.size(); i++ )
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtScale", scaleVector[i] << "," )
+ }
+#endif
+
+ // scale domain
+ if( !scaleDomain( sourceDomain, scaleVector, targetDomain ) )
+ {
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ RMInit::logOut << "Error: QtScale::evaluate( QtDataList* ) - empty result after scaling." << endl;
+ parseInfo.setErrorNo(419);
+ throw parseInfo;
+ }
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtBinaryFunc", "Dummy target domain: " << targetDomain << endl )
+
+ if(isWishedTargetSet)
+ {
+ translation = wishedTargetDomain.get_origin() - targetDomain.get_origin();
+ targetDomain.translate(translation);
+ }
+
+ // create a transient MDD object for the query result
+ MDDObj* resultMDD = new MDDObj( currentMDDObj->getMDDBaseType(), targetDomain );
+
+ //**********************
+ origin1 = r_Point(scaleVector.size()); // all zero!!
+ //**********************
+
+ // get all tiles
+ vector<Tile* >* tiles = currentMDDObj->intersect( qtMDDObj->getLoadDomain() );
+
+ //tile domain before & after
+ r_Minterval sourceTileDomain, destinationTileDomain;
+
+ //
+ // Algorithm A: Scale each Tile
+ //
+
+ // iterate over source tiles
+ for( vector<Tile*>::iterator tileIter = tiles->begin(); tileIter != tiles->end(); tileIter++ )
+ {
+ // get relevant area of source tile
+ sourceTileDomain = qtMDDObj->getLoadDomain().create_intersection( (*tileIter)->getDomain() );
+
+ // compute scaled tile domain and check if it exists
+ if( (*tileIter)->scaleGetDomain( sourceTileDomain, scaleVector, destinationTileDomain) )
+ {
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtBinaryFunc", "Destination tile domain: " << destinationTileDomain << endl )
+ // create a new transient tile
+ Tile* newTransTile = new Tile( destinationTileDomain, currentMDDObj->getCellType() );
+ newTransTile->execScaleOp( *tileIter, sourceTileDomain, origin1, scaleVector );
+
+ if(isWishedTargetSet)
+ ((r_Minterval&)newTransTile->getDomain()).translate(translation);
+
+ resultMDD->insertTile( newTransTile );
+ }
+ }
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)resultMDD );
+
+ // delete the tile vector, the tiles itself are deleted when the destructor
+ // of the MDD object is called
+ delete tiles;
+ tiles=NULL;
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ return returnValue;
+}
+
+
+void
+QtScale::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtScale Object " << getNodeType() << endl;
+
+ QtBinaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtScale::printAlgebraicExpression( ostream& s )
+{
+ s << "scale(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ",";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+void
+QtScale::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtScale", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ // by default, pass load domain to input1
+ if( input1 )
+ input1->optimizeLoad( trimList );
+ else
+ {
+ delete trimList;
+ trimList=NULL;
+ }
+}
+
+
+
+const QtTypeElement&
+QtScale::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtScale", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input1 && input2 )
+ {
+
+ // get input types
+ const QtTypeElement& inputType1 = input1->checkType( typeTuple );
+ const QtTypeElement& inputType2 = input2->checkType( typeTuple );
+
+ if( inputType1.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtScale::checkType() - first operand must be of type MDD." << endl;
+ parseInfo.setErrorNo(416);
+ throw parseInfo;
+ }
+
+ if( inputType2.getDataType() != QT_POINT && inputType2.getDataType() != QT_MINTERVAL &&
+ inputType2.getDataType() != QT_FLOAT && inputType2.getDataType() != QT_DOUBLE &&
+ !inputType2.isInteger() )
+ {
+ RMInit::logOut << "Error: QtScale::checkType() - second operand must be either of type Point, Integer or Float." << endl;
+ parseInfo.setErrorNo(417);
+ throw parseInfo;
+ }
+
+ // pass MDD type
+ dataStreamType = inputType1;
+ }
+ else
+ RMInit::logOut << "Error: QtScale::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
+int QtScale::scaleDomain( const r_Minterval& areaOp,
+ const vector<double>& scaleFactors,
+ r_Minterval &areaScaled )
+{
+ RMDBGENTER( 2, RMDebug::module_qlparser, "QtScale",
+ "scaleDomain( D: " << areaOp << ", F: " << scaleFactors << ", D: " << areaScaled << " )" )
+
+ try
+ {
+ areaScaled = areaOp.create_scale(scaleFactors);
+ }
+ catch(r_Error)
+ {
+ //error scaling
+ RMInit::logOut << "Error: QtScale::scaleDomain() - exception while determining scale target interval for " << areaOp << " and " << scaleFactors << endl;
+ return 0;
+ }
+
+ RMDBGEXIT( 2, RMDebug::module_qlparser, "QtScale", "scaleDomain(...) D: " << areaOp << " mapped to D: " << areaScaled )
+
+ return 1;
+}
+
+// origin1 von getLoadDomain
+// origin2 von getCurrentDomain
+
+int QtScale::scaleDomain( const r_Minterval& areaOp, const r_Point& origin1, const r_Point& origin2,
+ const vector<double>& scaleFactors, r_Minterval &areaScaled )
+{
+ RMDBGENTER( 2, RMDebug::module_qlparser,
+ "QtScale", "scaleDomain( D: " << areaOp << ", O1: " << origin1 << ", O2: " << origin2
+ << ", F: " << scaleFactors << " D: " << areaScaled << " )" )
+
+ r_Minterval tempIv=areaOp;
+
+ //reverse_translated with origin1
+ tempIv.reverse_translate(origin1);
+
+ //scale it normaly
+ if(!scaleDomain(tempIv, scaleFactors, areaScaled))
+ return 0;
+
+ //translate areaScaled to origin2
+ areaScaled.translate(origin2);
+
+ RMDBGEXIT( 2, RMDebug::module_qlparser, "QtScale", "scaledDomain(...) D: " << areaOp << " translated to D: " << areaScaled )
+
+ return 1;
+}
+
diff --git a/qlparser/qtbinaryfunc.hh b/qlparser/qtbinaryfunc.hh
new file mode 100644
index 0000000..a96a877
--- /dev/null
+++ b/qlparser/qtbinaryfunc.hh
@@ -0,0 +1,201 @@
+/*
+* 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>.
+*/
+#ifndef _QTBINARYFUNC_
+#define _QTBINARYFUNC_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtbinaryoperation.hh"
+#include "raslib/sinterval.hh"
+#include "raslib/minterval.hh"
+#include <vector>
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ * - why is this "binary"? they all have just one MDD!
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents a shift operation on MDD objects.
+
+*/
+
+class QtShift : public QtBinaryOperation
+{
+ public:
+ /// constructor getting the two operands
+ QtShift( QtOperation* mddOp, QtOperation* pointOp );
+
+ /// returns FALSE saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents an extend operation on MDD objects.
+
+*/
+
+class QtExtend : public QtBinaryOperation
+{
+ public:
+ /// constructor getting the two operands
+ QtExtend( QtOperation* mddOp, QtOperation* mintervalOp );
+ /**
+ FIXME: creates one single output tile, but should have a result tiling
+ */
+
+ /// returns FALSE saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /**
+ aux function for QtExtend::evaluate(): build up (recursing the dimension) a list of all spatial domains that sit in the corners between outerDomain and innerDomain; at the recursion bottom the resulting domain is added to the cornerList.
+ Preconditions:
+ - outerDomain, innerDomain defined values, of dimension maxDim
+ - currentDimension <= maxDim
+ - currentInterval has coordinates (no "*") set up to dimension currentDimension
+ @params outerDomain extended domain
+ @params innerDomain inner domain
+ @params currentDim current dimension to be inspected (0..maxDim)
+ @params maxDim maximum dimension to be inspected (#dimensions-1, suitable for indexing an r_Point or r_Minterval)
+ @params currentInterval current interval which is being built by iterating over its dimensions
+ @params cornerList list of corner intervals that is to be built; has to be deallocated by caller.
+ **/
+ void extendGetCornerTiles( r_Minterval outerDomain, r_Minterval innerDomain, r_Dimension currentDim, r_Dimension maxDim, r_Minterval currentInterval, vector<r_Minterval>* cornerList );
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents a scale operation on MDD objects.
+
+*/
+
+class QtScale : public QtBinaryOperation
+{
+ public:
+ /// constructor getting the two operands
+ QtScale( QtOperation* mddOp, QtOperation* pointOp );
+
+ /// returns FALSE saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ /// scale domains - initial version
+ virtual int scaleDomain( const r_Minterval& areaOp, const r_Point& origin1, const r_Point& origin2, const vector<double>& scaleFactors, r_Minterval &areaScaled );
+
+ /// scale domains - the used version
+ virtual int scaleDomain( const r_Minterval& areaOp, const vector<double>& scaleFactors, r_Minterval &areaScaled );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtbinaryfunc.icc"
+
+#endif
+
diff --git a/qlparser/qtbinaryfunc.icc b/qlparser/qtbinaryfunc.icc
new file mode 100644
index 0000000..a808b4a
--- /dev/null
+++ b/qlparser/qtbinaryfunc.icc
@@ -0,0 +1,47 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtShift::getNodeType() const
+{
+ return nodeType;
+}
+
+inline const QtNode::QtNodeType
+QtExtend::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtScale::getNodeType() const
+{
+ return nodeType;
+}
diff --git a/qlparser/qtbinaryinduce.cc b/qlparser/qtbinaryinduce.cc
new file mode 100644
index 0000000..9f7b1ba
--- /dev/null
+++ b/qlparser/qtbinaryinduce.cc
@@ -0,0 +1,959 @@
+/*
+* 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, QtBinaryInduce: $Id: qtbinaryinduce.cc,v 1.47 2003/12/27 20:39:35 rasdev Exp $";
+
+#include "raslib/rmdebug.hh"
+#include "debug.hh"
+
+#include "qlparser/qtbinaryinduce.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtcomplexdata.hh"
+#include "qlparser/qtconst.hh"
+#include "qlparser/qtstringdata.hh"
+
+#include "mddmgr/mddobj.hh"
+
+#include "catalogmgr/typefactory.hh"
+#include "relcatalogif/mdddomaintype.hh"
+
+#include "tilemgr/tile.hh"
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <memory>
+using namespace std;
+
+const QtNode::QtNodeType QtBinaryInduce::nodeType = QtNode::QT_BINARY_INDUCE;
+
+QtBinaryInduce::QtBinaryInduce( QtOperation* initInput1, QtOperation* initInput2, Ops::OpType initOpType )
+ : QtBinaryOperation( initInput1, initInput2 ),
+ opType( initOpType )
+{
+}
+
+
+
+QtData*
+QtBinaryInduce::computeOp( QtData* operand1, QtData* operand2 )
+{
+ RMDBCLASS( "QtBinaryInduce", "computeOp( QtData*, QtData* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+
+ if ( operand1->getDataType() == QT_MDD &&
+ operand2->getDataType() == QT_MDD )
+ {
+ QtMDD* mdd1 = (QtMDD*) operand1;
+ QtMDD* mdd2 = (QtMDD*) operand2;
+
+ const BaseType* resultBaseType = ((MDDBaseType*)(dataStreamType.getType()))->getBaseType();
+
+ returnValue = computeBinaryMDDOp( mdd1, mdd2, resultBaseType );
+ }
+ else if( operand1->getDataType() == QT_MDD &&
+ operand2->isScalarData() )
+ {
+ QtMDD* mdd = (QtMDD*) operand1;
+ QtScalarData* scalar = (QtScalarData*) operand2;
+
+ const BaseType* resultBaseType = ((MDDBaseType*)(dataStreamType.getType()))->getBaseType();
+
+ returnValue = computeUnaryMDDOp( mdd, scalar, resultBaseType, 2 );
+ }
+ else if( operand1->isScalarData() &&
+ operand2->getDataType() == QT_MDD )
+ {
+ QtMDD* mdd = (QtMDD*) operand2;
+ QtScalarData* scalar = (QtScalarData*) operand1;
+
+ const BaseType* resultBaseType = ((MDDBaseType*)(dataStreamType.getType()))->getBaseType();
+
+ returnValue = computeUnaryMDDOp( mdd, scalar, resultBaseType, 1 );
+ }
+ else if( operand1->isScalarData() &&
+ operand2->isScalarData() )
+ {
+ QtScalarData* scalar1 = (QtScalarData*) operand1;
+ QtScalarData* scalar2 = (QtScalarData*) operand2;
+
+ BaseType* resultBaseType = (BaseType*)(dataStreamType.getType());
+
+ returnValue = computeBinaryOp( scalar1, scalar2, resultBaseType );
+ }
+ else if( operand1->getDataType() == QT_STRING && operand2->getDataType() == QT_STRING )
+ {
+ // opType == Ops::OP_EQUAL
+ QtStringData* strObj1 = (QtStringData*) operand1;
+ QtStringData* strObj2 = (QtStringData*) operand2;
+
+ bool booleanResult = strObj1->getStringData() == strObj2->getStringData();
+
+ returnValue = new QtAtomicData( booleanResult );
+ }
+
+ return returnValue;
+}
+
+
+
+QtData*
+QtBinaryInduce::computeUnaryMDDOp( QtMDD* operand1, QtScalarData* operand2, const BaseType* resultBaseType, int scalarPos )
+{
+ RMDBCLASS( "QtBinaryInduce", "computeUnaryMDDOp( QtMDD*, QtScalarData*, BaseType*, int )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+
+ // get the MDD object
+ MDDObj* op = operand1->getMDDObject();
+
+ // create ULong type with QtIntData value
+ const BaseType* constBaseType = operand2->getValueType();
+ const char* constValue = operand2->getValueBuffer();
+
+ // get the area, where the operation has to be applied
+ const r_Minterval &areaOp = operand1->getLoadDomain();
+
+ // contains all tiles of the operand
+ vector<Tile*>* allTiles=NULL;
+
+ // iterator for tiles
+ vector<Tile*>::iterator tileIt;
+
+ // create MDDObj for result
+ MDDDomainType* mddBaseType = new MDDDomainType( "tmp", resultBaseType, areaOp );
+ TypeFactory::addTempType( mddBaseType );
+
+ MDDObj* mddres = new MDDObj( mddBaseType, areaOp );
+
+ // get all tiles in relevant area
+ allTiles = op->intersect(areaOp);
+ tileIt = allTiles->begin();
+ //auto_ptr<BinaryOp> myOp(NULL);
+ BinaryOp* myOp = NULL;
+ if (tileIt != allTiles->end())
+ {
+ if (scalarPos == 1)
+ //myOp.reset(Ops::getBinaryOp(opType, resultBaseType, constBaseType, (*tileIt)->getType()));
+ myOp = (Ops::getBinaryOp(opType, resultBaseType, constBaseType, (*tileIt)->getType()));
+ else
+ //myOp.reset(Ops::getBinaryOp(opType, resultBaseType, (*tileIt)->getType(), constBaseType));
+ myOp = (Ops::getBinaryOp(opType, resultBaseType, (*tileIt)->getType(), constBaseType));
+ }
+ // and iterate over them
+ for( ; tileIt != allTiles->end(); tileIt++ )
+ {
+ // domain of the actual tile
+ const r_Minterval &tileDom = (*tileIt)->getDomain();
+
+ // domain of the relevant area of the actual tile
+ r_Minterval intersectDom( tileDom.create_intersection( areaOp ) );
+
+ // create tile for result
+ Tile* resTile = new Tile( intersectDom, resultBaseType );
+
+ //
+ // carry out operation on the relevant area of the tiles
+ //
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtScale", \
+ char* typeStructure = resTile->getType()->getTypeStructure(); \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " result tile, area " << intersectDom << \
+ ", type " << resTile->getType()->getTypeName() << \
+ ", structure " << typeStructure << endl ) \
+ free( typeStructure ); typeStructure=NULL; \
+ \
+ typeStructure = (*tileIt)->getType()->getTypeStructure(); \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " operand1 tile, area " << intersectDom << \
+ ", type " << (*tileIt)->getType()->getTypeName() << \
+ ", structure " << typeStructure << endl ) \
+ free( typeStructure ); typeStructure=NULL; \
+
+ typeStructure = constBaseType->getTypeStructure(); \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " constant type " << constBaseType->getTypeName() << \
+ ", structure " << typeStructure << \
+ ", value " ) \
+ free( typeStructure ); typeStructure=NULL; \
+ \
+ for( int x=0; x<constBaseType->getSize(); x++ ) \
+ RMInit::dbgOut << hex << (int)(constValue[x]); \
+ RMInit::dbgOut << dec << endl; \
+ )
+
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " before execConstOp" << endl )
+
+ resTile->execConstOp( myOp, intersectDom, (*tileIt), intersectDom, constValue, scalarPos );
+ //resTile->execConstOp( opType, intersectDom, (*tileIt), intersectDom, constValue, constBaseType, scalarPos );
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " after execConstOp" << endl )
+
+ // insert Tile in result tile
+ mddres->insertTile( resTile );
+ }
+ delete myOp;
+ myOp = NULL;
+
+ // delete tile vector
+ delete allTiles;
+ allTiles=NULL;
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)mddres );
+
+ // The following is now done, when the last reference is deleted.
+ // delete the obsolete MDD object
+ // delete op;
+
+ return returnValue;
+}
+
+
+
+QtData*
+QtBinaryInduce::computeBinaryMDDOp( QtMDD* operand1, QtMDD* operand2, const BaseType* resultBaseType )
+{
+ RMDBCLASS( "QtBinaryInduce", "computeBinaryMDDOp( QtMDD*, QtMDD*, BaseType* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+
+ // get the MDD objects
+ MDDObj* op1 = operand1->getMDDObject();
+ MDDObj* op2 = operand2->getMDDObject();
+
+ // get the areas, where the operation has to be applied
+ const r_Minterval &areaOp1 = operand1->getLoadDomain();
+ const r_Minterval &areaOp2 = operand2->getLoadDomain();
+
+ // Check, if the domains are compatible which means that they have the same
+ // dimensionality and each dimension has the same number of elements.
+ if( areaOp1.get_extent() == areaOp2.get_extent() )
+ {
+ // contains all tiles of op1
+ vector<Tile*>* allTilesOp1=NULL;
+
+ // contains all tiles of op2 which intersect a given op1 Tile in the relevant area.
+ vector<Tile*>* intersectTilesOp2=NULL;
+
+ // iterators for tiles of the MDDs
+ vector<Tile*>::iterator tileOp1It;
+ vector<Tile*>::iterator intersectTileOp2It;
+
+ // intersection of domains in relevant area.
+ r_Minterval intersectDom;
+
+ // pointer to generated result tile
+ Tile* resTile=NULL;
+
+ // MDDObj for result
+ MDDObj* mddres=NULL;
+
+ // translations between the two areas
+ r_Point offset12(areaOp1.dimension());
+ r_Point offset21(areaOp1.dimension());
+
+ // calculate translations
+ r_Point originOp1 = areaOp1.get_origin();
+ r_Point originOp2 = areaOp2.get_origin();
+ for(r_Dimension i = 0; i<areaOp1.dimension(); i++)
+ {
+ offset12[i] = originOp2[i] - originOp1[i];
+ offset21[i] = originOp1[i] - originOp2[i];
+ }
+
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " Domain op1 " << areaOp1 << " op2 " << areaOp2 )
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " Translation vector " << offset12 )
+
+ // create MDDObj for result
+ MDDDomainType* mddBaseType = new MDDDomainType( "tmp", resultBaseType, areaOp1 );
+ TypeFactory::addTempType( mddBaseType );
+
+ mddres = new MDDObj( mddBaseType, areaOp1 );
+
+ // get all tiles in relevant area of MDD op1
+ allTilesOp1 = op1->intersect(areaOp1);
+
+ // cout << "INTERSECT" << areaOp1 << endl;
+ // for( tileOp1It = allTilesOp1->begin(); tileOp1It != allTilesOp1->end(); tileOp1It++ )
+ // cout << (*tileOp1It)->getDomain() << endl;
+
+ // and iterate over them
+ auto_ptr<BinaryOp> myOp(Ops::getBinaryOp(opType, mddBaseType->getBaseType(), op1->getCellType(), op2->getCellType()));
+ for( tileOp1It = allTilesOp1->begin(); tileOp1It != allTilesOp1->end(); tileOp1It++ )
+ {
+ // domain of the op1 tile
+ const r_Minterval &tileOp1Dom = (*tileOp1It)->getDomain();
+
+ // relevant area of op1's domain
+ r_Minterval intersectionTileOp1Dom( tileOp1Dom.create_intersection( areaOp1 ) );
+
+ // intersect relevant area of the tile with MDD op2 (including translation)
+ intersectTilesOp2 = op2->intersect(intersectionTileOp1Dom.create_translation(offset12));
+
+ // cout << "INTERSECT" << tileOp1Dom.create_translation(offset12) << endl;
+ // for( intersectTileOp2It = intersectTilesOp2->begin();
+ // intersectTileOp2It != intersectTilesOp2->end();
+ // intersectTileOp2It++ )
+ // cout << (*intersectTileOp2It)->getDomain() << endl;
+
+ // iterate over intersecting tiles
+ for( intersectTileOp2It = intersectTilesOp2->begin();
+ intersectTileOp2It != intersectTilesOp2->end();
+ intersectTileOp2It++ )
+ {
+ const r_Minterval &tileOp2Dom = (*intersectTileOp2It)->getDomain();
+
+ // the relevant domain is the intersection of the
+ // domains of the two tiles with the relevant area.
+ intersectDom = tileOp1Dom.create_intersection(tileOp2Dom.create_translation(offset21));
+
+ intersectDom.intersection_with(areaOp1);
+
+ // create tile for result
+ resTile = new Tile( intersectDom, resultBaseType );
+
+ //
+ // carry out operation on the relevant area of the tiles
+ //
+
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " before execBinaryOp" << endl )
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " result tile, area " << intersectDom <<
+ ", type " << resTile->getType()->getTypeName() << endl )
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " operand1 tile, area " << intersectDom <<
+ ", type " << (*tileOp1It)->getType()->getTypeName() << endl )
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " operand2 tile, type " << (*tileOp1It)->getType()->getTypeName() << endl )
+ resTile->execBinaryOp(&(*myOp), intersectDom, (*tileOp1It), intersectDom, (*intersectTileOp2It), intersectDom.create_translation(offset12));
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", " after execBinaryOp" << endl )
+
+ // insert Tile in result mddobj
+ mddres->insertTile( resTile );
+ }
+
+ delete intersectTilesOp2;
+ intersectTilesOp2=NULL;
+ }
+
+ delete allTilesOp1;
+ allTilesOp1=NULL;
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)mddres );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtBinaryInduce::computeBinaryMDDOp() - domains of the operands are incompatible." << endl;
+ RMInit::logOut << "areaOp1 " << areaOp1 << " with extent " << areaOp1.get_extent() << endl;
+ RMInit::logOut << "areaOp2 " << areaOp2 << " with extent " << areaOp2.get_extent() << endl;
+
+ parseInfo.setErrorNo(351);
+ throw parseInfo;
+ }
+
+ // The following is now done, when the last reference is deleted.
+ // delete obsolete MDD objects
+ // delete op1;
+ // delete op2;
+
+ return returnValue;
+}
+
+
+
+QtData*
+QtBinaryInduce::computeBinaryOp( QtScalarData* operand1, QtScalarData* operand2, const BaseType* resultBaseType )
+{
+ RMDBCLASS( "QtBinaryInduce", "computeBinaryOp( QtScalarData*, QtScalarData*, BaseType*, Ops::OpType )", "qlparser", __FILE__, __LINE__ )
+
+ QtScalarData* scalarDataObj = NULL;
+
+ // allocate memory for the result
+ char* resultBuffer = new char[ resultBaseType->getSize() ];
+
+ Ops::execBinaryConstOp( opType, resultBaseType,
+ operand1->getValueType(), operand2->getValueType(),
+ resultBuffer,
+ operand1->getValueBuffer(), operand2->getValueBuffer() );
+
+ if( resultBaseType->getType() == STRUCT )
+ scalarDataObj = new QtComplexData();
+ else
+ scalarDataObj = new QtAtomicData();
+
+ scalarDataObj->setValueType ( resultBaseType );
+ scalarDataObj->setValueBuffer( resultBuffer );
+
+ return scalarDataObj;
+}
+
+
+
+QtData*
+QtBinaryInduce::evaluate( QtDataList* inputList )
+{
+ QtData* returnValue = NULL;
+ QtData* operand1 = NULL;
+ QtData* operand2 = NULL;
+
+ if( getOperands( inputList, operand1, operand2 ) )
+ {
+ returnValue = computeOp( operand1, operand2 );
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+ }
+ return returnValue;
+}
+
+
+
+const QtTypeElement&
+QtBinaryInduce::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtBinaryInduce", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input1 && input2 )
+ {
+
+ // get input types
+ const QtTypeElement& inputType1 = input1->checkType( typeTuple );
+ const QtTypeElement& inputType2 = input2->checkType( typeTuple );
+
+ RMDBGIF( 1, RMDebug::module_qlparser, "QtBinaryInduce", \
+ RMInit::dbgOut << "Operand 1: " << flush; \
+ inputType1.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ \
+ RMInit::dbgOut << "Operand 2: " << flush; \
+ inputType2.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtBinaryInduce", "Operation " << opType ) \
+ )
+
+ if( inputType1.getDataType() == QT_MDD &&
+ inputType2.getDataType() == QT_MDD )
+ {
+ const BaseType* baseType1 = ((MDDBaseType*)(inputType1.getType()))->getBaseType();
+ const BaseType* baseType2 = ((MDDBaseType*)(inputType2.getType()))->getBaseType();
+
+ const BaseType* resultBaseType = Ops::getResultType( opType, baseType1, baseType2 );
+
+ if( !resultBaseType )
+ {
+ RMInit::logOut << "Error: QtBinaryInduce::checkType() - binary induce (MDD + MDD): operand types are incompatible." << endl;
+ parseInfo.setErrorNo(363);
+ throw parseInfo;
+ }
+
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+
+ dataStreamType.setType( resultMDDType );
+ }
+ else if( inputType1.getDataType() == QT_MDD &&
+ inputType2.isBaseType() )
+ {
+ const BaseType* baseType1 = ((MDDBaseType*)(inputType1.getType()))->getBaseType();
+ BaseType* baseType2 = (BaseType*)(inputType2.getType());
+
+ const BaseType* resultBaseType = Ops::getResultType( opType, baseType1, baseType2 );
+
+ if( !resultBaseType )
+ {
+ RMInit::logOut << "Error: QtBinaryInduce::checkType() - unary induce (MDD + BaseType): operand types are incompatible." << endl;
+ parseInfo.setErrorNo(364);
+ throw parseInfo;
+ }
+
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+
+ dataStreamType.setType( resultMDDType );
+ }
+ else if( inputType1.isBaseType() &&
+ inputType2.getDataType() == QT_MDD )
+ {
+ BaseType* baseType1 = (BaseType*)(inputType1.getType());
+ const BaseType* baseType2 = ((MDDBaseType*)(inputType2.getType()))->getBaseType();
+
+ const BaseType* resultBaseType = Ops::getResultType( opType, baseType1, baseType2 );
+
+ if( !resultBaseType )
+ {
+ RMInit::logOut << "Error: QtBinaryInduce::checkType() - unary induce (BaseType + MDD): operand types are incompatible." << endl;
+ parseInfo.setErrorNo(364);
+ throw parseInfo;
+ }
+
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+
+ dataStreamType.setType( resultMDDType );
+ }
+ else if( inputType1.isBaseType() &&
+ inputType2.isBaseType() )
+ {
+ BaseType* baseType1 = (BaseType*)(inputType1.getType());
+ BaseType* baseType2 = (BaseType*)(inputType2.getType());
+
+ const BaseType* resultBaseType = Ops::getResultType( opType, baseType1, baseType2 );
+
+ if( !resultBaseType )
+ {
+ RMInit::logOut << "Error: QtBinaryInduce::checkType() - BaseType + BaseType : operand types are incompatible." << endl;
+
+ parseInfo.setErrorNo(365);
+ throw parseInfo;
+ }
+
+ dataStreamType.setType( resultBaseType );
+ }
+ else if( inputType1.getDataType() == QT_STRING &&
+ inputType2.getDataType() == QT_STRING )
+ {
+ if( opType != Ops::OP_EQUAL )
+ {
+ RMInit::logOut << "Error: QtBinaryInduce::checkType() - String + String : operation is not supported on strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_BOOL );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtBinaryInduce::checkType() - operation is not supported on these data types." << endl;
+ parseInfo.setErrorNo(403);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtBinaryInduce::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
+
+const QtNode::QtNodeType QtPlus::nodeType = QT_PLUS;
+
+QtPlus::QtPlus( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_PLUS )
+{
+}
+
+
+/*
+void
+QtPlus::rewriteOps()
+{
+ RMDBCLASS( "QtPlus", "rewriteOps()", "qlparser", __FILE__, __LINE__ )
+
+ if( input1 && input2 )
+ {
+ if( nodeType == input2->getNodeType() )
+ {
+ // changed from log to debug output -- PB 2003-nov-20
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtPlus", "rewriteOps: rule (left deep tree): A+(B+C) -> (B+C)+A" );
+
+ // more than one equal binary operator, make standard form of the tree
+
+ QtBinaryOperation* nodeR = (QtBinaryOperation*) input2;
+ QtOperation* nodeRL = nodeR->getInput1();
+
+ getParent()->setInput( this, nodeR );
+ nodeR->setInput1( this );
+ this->setInput2( nodeRL );
+ nodeR->rewriteOps();
+ }
+ else
+ {
+ input1->rewriteOps();
+ input2->rewriteOps();
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtPlus::rewriteOps() - the operand branch is invalid." << endl;
+}
+*/
+
+/*
+void
+QtPlus::sortAssociativeOps()
+{
+ ENTER( "QtPlus::sortAssociativeOps() -- input1 is " << (input1?"not null":"null") << ", input 2 is " << (input2?"not null":"null") );
+
+ if( input1 && input2 )
+ {
+ if( nodeType == input1->getNodeType() )
+ {
+ // associative law is applicable
+
+ QtOperation* node = input1->getUniqueOrder( nodeType );
+
+ if( node && node->getSpelling().compare( input2->getSpelling() ) > 0 )
+ {
+ node->getParent()->setInput( node, input2 );
+ setInput2( node );
+ }
+ }
+ else
+ {
+ bool compare = ( input1->getSpelling().compare( input2->getSpelling() ) > 0 );
+ TALK( "QtPlus::sortAssociativeOps(): compare -> " << compare );
+ if( compare )
+ {
+ // changed from log to debug output -- PB 2003-nov-20
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtPlus", "sortAssociativeOps: applying rule 'associativity'" );
+
+ QtOperation* node = input1;
+
+ setInput1( input2 );
+ setInput2( node );
+ };
+
+ };
+
+ input1->sortAssociativeOps();
+ }
+ else
+ RMInit::logOut << "Error: QtPlus::sortAssociativeOps() - the operand branch is invalid." << endl;
+
+ LEAVE( "QtPlus::sortAssociativeOps()" );
+}
+*/
+
+
+QtOperation*
+QtPlus::getUniqueOrder( const QtNode::QtNodeType ID )
+{
+ RMDBCLASS( "QtPlus", "getUniqueOrder( const QtNode::QtNodeType )", "qlparser", __FILE__, __LINE__ )
+
+ QtOperation* returnValue = NULL;
+
+ if( nodeType == ID )
+ {
+ QtOperation* node = input1->getUniqueOrder( nodeType );
+
+ if( node )
+ {
+ if( ( node->getSpelling().compare( input2->getSpelling() ) ) > 0 )
+ returnValue = node;
+ else
+ returnValue = input2;
+ }
+ else
+ RMInit::logOut << "Error: QtMult::getUniqueOrder(): Query tree invalid" << endl;
+ }
+ else
+ returnValue = this;
+
+ return returnValue;
+}
+
+
+
+void
+QtPlus::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtPlus Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+
+void
+QtPlus::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " + ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtMinus::nodeType = QT_MINUS;
+
+QtMinus::QtMinus( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_MINUS )
+{
+}
+
+
+
+bool
+QtMinus::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+void
+QtMinus::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtMinus Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+
+void
+QtMinus::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " - ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+
+const QtNode::QtNodeType QtMult::nodeType = QT_MULT;
+
+QtMult::QtMult( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_MULT )
+{
+}
+
+
+/*
+void
+QtMult::rewriteOps()
+{
+ RMDBCLASS( "QtMult", "rewriteOps()", "qlparser", __FILE__, __LINE__ )
+
+ if( input1 && input2 )
+ {
+ if( nodeType == input2->getNodeType() )
+ {
+ RMInit::logOut << "> rule (left deep tree): A*(B*C) -> (B*C)*A" << endl;
+
+ // more than one equal binary operator, make standard form of the tree
+
+ QtBinaryOperation* nodeR = (QtBinaryOperation*) input2;
+ QtOperation* nodeRL = nodeR->getInput1();
+
+ getParent()->setInput( this, nodeR );
+ nodeR->setInput1( this );
+ this->setInput2( nodeRL );
+ nodeR->rewriteOps();
+ }
+ else
+ {
+ input1->rewriteOps();
+ input2->rewriteOps();
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtMult::rewriteOps() - the operand branch is invalid." << endl;
+}
+*/
+
+/*
+void
+QtMult::sortAssociativeOps()
+{
+ RMDBCLASS( "QtMult", "sortAssociativeOps()", "qlparser", __FILE__, __LINE__ )
+
+ if( input1 && input2 )
+ {
+ if( nodeType == input1->getNodeType() )
+ {
+ // associative law is applicable
+
+ QtOperation* node = input1->getUniqueOrder( nodeType );
+
+ if( node && node->getSpelling().compare( input2->getSpelling() ) > 0 )
+ {
+ node->getParent()->setInput( node, input2 );
+ setInput2( node );
+ };
+ }
+ else
+ {
+ if( input1->getSpelling().compare( input2->getSpelling() ) > 0 )
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtMult", "sortAssociativeOps: rule (associativity): A * B -> B * A" );
+
+ QtOperation* node = input1;
+
+ setInput1( input2 );
+ setInput2( node );
+ };
+ }
+
+ input1->sortAssociativeOps();
+ }
+ else
+ RMInit::logOut << "Error: QtMult::sortAssociativeOps() - the operand branch is invalid." << endl;
+}
+*/
+
+
+QtOperation*
+QtMult::getUniqueOrder( const QtNode::QtNodeType ID )
+{
+ RMDBCLASS( "QtMult", "getUniqueOrder( const string )", "qlparser", __FILE__, __LINE__ )
+
+ QtOperation* returnValue = NULL;
+
+ if( nodeType == ID )
+ {
+ QtOperation* node = input1->getUniqueOrder( nodeType );
+
+ if( node )
+ {
+ if( node->getSpelling().compare( input2->getSpelling() ) > 0 )
+ returnValue = node;
+ else
+ returnValue = input2;
+ }
+ else
+ RMInit::logOut << "Error: QtMult::getUniqueOrder(): Query tree invalid" << endl;
+ }
+ else
+ returnValue = this;
+
+ return returnValue;
+}
+
+
+
+void
+QtMult::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtMult Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+
+void
+QtMult::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " * ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtDiv::nodeType = QT_DIV;
+
+QtDiv::QtDiv( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_DIV )
+{
+}
+
+
+
+bool
+QtDiv::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+void
+QtDiv::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtDiv Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+
+void
+QtDiv::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " / ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
diff --git a/qlparser/qtbinaryinduce.hh b/qlparser/qtbinaryinduce.hh
new file mode 100644
index 0000000..de744e3
--- /dev/null
+++ b/qlparser/qtbinaryinduce.hh
@@ -0,0 +1,261 @@
+#ifndef _QTBINARYINDUCE_
+#define _QTBINARYINDUCE_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtbinaryoperation.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtscalardata.hh"
+
+#include "catalogmgr/ops.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+The class hierarchy guarantees no type safety. Type checking is done at
+execution time.
+
+The operations greater and greater equal are mapped to QtLess and QtLessEqual.
+*/
+
+class QtBinaryInduce : public QtBinaryOperation
+{
+ public:
+ /// constructor getting the two operands
+ QtBinaryInduce( QtOperation* input1, QtOperation* input2, Ops::OpType initOpType );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ protected:
+ /// computes the binary operation
+ QtData* computeOp( QtData* operand1, QtData* operand2 );
+
+ /// computes an unary induce operation with one MDD object and a scalar value either being atomic or complex constant
+ QtData* computeUnaryMDDOp( QtMDD* operand1, QtScalarData* operand2, const BaseType* resultBaseType, int scalarPos=1 );
+ /**
+ The method carries out the unary induce operation specified by {\tt operation} on the two operands. {\tt scalarPos }
+ determines if the scalar value is the first (=1, default) or the second (=2) operand in the operation. For
+ the result, a new transient MDD object is created and returned. In the end, the MDD object of the first operand
+ is freed.
+ */
+
+ /// computes a binary induce operation on two MDD objects
+ QtData* computeBinaryMDDOp( QtMDD* operand1, QtMDD* operand2, const BaseType* resultBaseType );
+ /**
+ The method carries out the binary induce operation specified by {\tt operation} on the two operands. For
+ the result, a new transient MDD object is created and returned. In the end, the MDD objects of the operands
+ are freed.
+ */
+
+ /// computes a binary operation on two scalar objects
+ QtData* computeBinaryOp( QtScalarData* operand1, QtScalarData* operand2, const BaseType* resultBaseType );
+ /**
+ The method carries out the binary operation specified by {\tt operation} on the two operands.
+ */
+
+// private:
+ // type of operation
+ Ops::OpType opType;
+
+ private:
+ /// atribute for identification of nodes
+ static const QtNodeType nodeType;
+
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtPlus : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtPlus( QtOperation* input1, QtOperation* input2 );
+
+ /// optimizes the tree
+// virtual void rewriteOps();
+
+ /// optimizes the tree
+// virtual void sortAssociativeOps();
+
+ ///for associative law
+ virtual QtOperation* getUniqueOrder( const QtNode::QtNodeType ID );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtMinus : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtMinus( QtOperation* input1, QtOperation* input2 );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// returns FALSE saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtMult : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtMult( QtOperation* input1, QtOperation* input2 );
+
+ /// optimizes the tree
+// virtual void rewriteOps();
+
+ /// optimizes the tree
+// virtual void sortAssociativeOps();
+
+ /// optimizes the tree
+ virtual QtOperation* getUniqueOrder( const QtNode::QtNodeType ID );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtDiv : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtDiv( QtOperation* input1, QtOperation* input2 );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// returns FALSE saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+#include "qlparser/qtbinaryinduce.icc"
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtbinaryinduce.icc b/qlparser/qtbinaryinduce.icc
new file mode 100644
index 0000000..6a7caa9
--- /dev/null
+++ b/qlparser/qtbinaryinduce.icc
@@ -0,0 +1,56 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtPlus::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtMinus::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtMult::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtDiv::getNodeType() const
+{
+ return nodeType;
+}
+
diff --git a/qlparser/qtbinaryinduce2.cc b/qlparser/qtbinaryinduce2.cc
new file mode 100644
index 0000000..c12479c
--- /dev/null
+++ b/qlparser/qtbinaryinduce2.cc
@@ -0,0 +1,919 @@
+/*
+* 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, QtBinaryInduce: $Id: qtbinaryinduce2.cc,v 1.25 2002/09/11 14:48:51 hoefner Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtbinaryinduce2.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtconst.hh"
+
+#include "mddmgr/mddobj.hh"
+
+#include "catalogmgr/typefactory.hh"
+
+#include <iostream>
+#include <string>
+#include <vector>
+using namespace std;
+
+const QtNode::QtNodeType QtIs::nodeType = QT_IS;
+
+QtIs::QtIs( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_EQUAL )
+{
+}
+
+/*
+void
+QtIs::checkIdempotency()
+{
+ if( input1->getSpelling().compare( input2->getSpelling() ) == 0 )
+ {
+ RMInit::logOut << "> rule (idempotency): A IS A -> TRUE" << endl;
+
+ getParent()->setInput( this, new QtConst( new QtAtomicData( 1 ) ) );
+
+ // delete the node itself and its descendants
+ delete this;
+ };
+}
+*/
+
+void
+QtIs::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtIs Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+void
+QtIs::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " is ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+const QtNode::QtNodeType QtAnd::nodeType = QT_AND;
+
+QtAnd::QtAnd( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_AND )
+{
+}
+
+/*
+void
+QtAnd::checkIdempotency()
+{
+ if( input2->getNodeType() == QtNode::QT_CONST &&
+ ((QtConst*)input2)->getDataObj()->getDataType() == QT_BOOL )
+ {
+ QtAtomicData* boolData = (QtAtomicData*)((QtConst*)input2)->getDataObj();
+
+ if( boolData->getUnsignedValue() )
+ {
+ RMInit::logOut << "> rule (idempotency): A AND TRUE -> A" << endl;
+
+ getParent()->setInput( this, input1 );
+
+ // delete the node itself and its descendants but not input1
+ setInput1(NULL);
+ delete this;
+ }
+ else
+ {
+ if( input1->getAreaType() == QtNode::QT_AREA_SCALAR )
+ {
+ RMInit::logOut << "> rule (idempotency): A (scalar) AND FALSE -> FALSE" << endl;
+
+ getParent()->setInput( this, input2 );
+
+ // delete the node itself and its descendants but not input2
+ setInput2(NULL);
+ delete this;
+ };
+ }
+ }
+ else
+ if( input1->getNodeType() == QtNode::QT_CONST &&
+ ((QtConst*)input1)->getDataObj()->getDataType() == QT_BOOL )
+ {
+ QtAtomicData* boolData = (QtAtomicData*)((QtConst*)input1)->getDataObj();
+
+ if( boolData->getUnsignedValue() )
+ {
+ RMInit::logOut << "> rule (idempotency): TRUE AND A -> A" << endl;
+
+ getParent()->setInput( this, input2 );
+
+ // delete the node itself and its descendants but not input2
+ setInput2(NULL);
+ delete this;
+ }
+ else
+ {
+ if( input2->getAreaType() == QtNode::QT_AREA_SCALAR )
+ {
+ RMInit::logOut << "> rule (idempotency): FALSE AND A (scalar) -> FALSE" << endl;
+
+ getParent()->setInput( this, input1 );
+
+ // delete the node itself and its descendants but not input1
+ setInput1(NULL);
+ delete this;
+ };
+ };
+ }
+ else
+ if( input1->getSpelling().compare( input2->getSpelling() ) == 0 )
+ {
+ RMInit::logOut << "> rule (idempotency): A AND A -> A" << endl;
+
+ getParent()->setInput( this, input1 );
+
+ // delete the node itself and its descendants but not input1
+ setInput1(NULL);
+ delete this;
+ }
+}
+*/
+
+
+
+/*
+void
+QtAnd::rewriteOps()
+{
+ if( input1 && input2 )
+ {
+ if( input1->getNodeType() == QtNode::QT_SOME &&
+ input2->getNodeType() == QtNode::QT_ALL )
+ {
+ RMInit::logOut << "> rule (condenser order): SOME_CELLS AND ALL_CELLS -> ALL_CELLS AND SOME_CELLS" << endl;
+
+ // order condenser expressions
+
+ QtOperation* node1 = getInput1();
+ QtOperation* node2 = getInput2();
+
+ setInput1( node2 );
+ setInput2( node1 );
+ };
+ }
+ else
+ RMInit::logOut << "Error: QtAnd::rewriteOps() - the operand branch is invalid." << endl;
+}
+*/
+
+
+QtData*
+QtAnd::evaluate( QtDataList* inputList )
+{
+ /*
+ // RUNTIME OPTIMIZATION: FALSE AND A -> MDD(FALSE)
+ // A AND FALSE -> MDD(FALSE)
+ // TRUE AND A -> A
+ // A AND TRUE -> A
+ */
+
+ QtData* returnValue = NULL;
+
+ if( input1->getDataStreamType().getDataType() == QT_BOOL &&
+ input2->getDataStreamType().getDataType() == QT_BOOL )
+ {
+ // RUNTIME OPTIMIZATION: FALSE AND A -> FALSE
+ // TRUE AND A -> A
+
+ QtData* operand1=NULL;
+
+ if( getOperand( inputList, operand1, 1 ) )
+ {
+ bool op1 = ((QtAtomicData*)operand1)->getUnsignedValue();
+
+ if( op1 )
+ {
+ // first operand is obsolete
+ if( operand1 ) operand1->deleteRef();
+
+ QtData* operand2=NULL;
+
+ if( getOperand( inputList, operand2, 2 ) )
+ {
+ returnValue = operand2;
+ }
+ }
+ else
+ {
+ returnValue = operand1;
+ RMDBGONCE(1, RMDebug::module_qlparser, "QtAnd", " -> FALSE AND A evaluates FALSE")
+ }
+ }
+ }
+ else
+ returnValue = QtBinaryInduce::evaluate( inputList );
+
+ return returnValue;
+}
+
+
+void
+QtAnd::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtAnd Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+void
+QtAnd::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " and ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtOr::nodeType = QT_OR;
+
+QtOr::QtOr( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_OR )
+{
+}
+
+/*
+void
+QtOr::checkIdempotency()
+{
+ if( input2->getNodeType() == QtNode::QT_CONST &&
+ ((QtConst*)input2)->getDataObj()->getDataType() == QT_BOOL )
+ {
+ QtAtomicData* boolData = (QtAtomicData*)((QtConst*)input2)->getDataObj();
+
+ if( boolData->getUnsignedValue() )
+ {
+ if( input1->getAreaType() == QtNode::QT_AREA_SCALAR )
+ {
+ RMInit::logOut << "> rule (idempotency): A (scalar) OR TRUE -> TRUE" << endl;
+
+ getParent()->setInput( this, input2 );
+
+ // delete the node itself and its descendants but not input2
+ setInput2(NULL);
+ delete this;
+ };
+ }
+ else
+ {
+ RMInit::logOut << "> rule (idempotency): A OR FALSE -> A" << endl;
+
+ getParent()->setInput( this, input1 );
+
+ // delete the node itself and its descendants but not input1
+ setInput1(NULL);
+ delete this;
+ }
+ }
+ else
+ if( input1->getNodeType() == QtNode::QT_CONST &&
+ ((QtConst*)input1)->getDataObj()->getDataType() == QT_BOOL )
+ {
+ QtAtomicData* boolData = (QtAtomicData*)((QtConst*)input1)->getDataObj();
+
+ if( boolData->getUnsignedValue() )
+ {
+ if( input2->getAreaType() == QtNode::QT_AREA_SCALAR )
+ {
+ RMInit::logOut << "> rule (idempotency): TRUE OR A (scalar) -> TRUE" << endl;
+
+ getParent()->setInput( this, input1 );
+
+ // delete the node itself and its descendants but not input1
+ setInput1(NULL);
+ delete this;
+ };
+ }
+ else
+ {
+ RMInit::logOut << "> rule (idempotency): FALSE OR A -> A" << endl;
+
+ getParent()->setInput( this, input2 );
+
+ // delete the node itself and its descendants but not input2
+ setInput2(NULL);
+ delete this;
+ };
+ }
+ else
+ if( input1->getSpelling().compare( input2->getSpelling() ) == 0 )
+ {
+ RMInit::logOut << "> rule (idempotency): A OR A -> A" << endl;
+
+ getParent()->setInput( this, input1 );
+
+ // delete the node itself and its descendants but not input1
+ setInput1(NULL);
+ delete this;
+ };
+}
+*/
+
+
+/*
+void
+QtOr::rewriteOps()
+{
+ if( input1 && input2 )
+ {
+ if( input1->getNodeType() == QtNode::QT_ALL &&
+ input2->getNodeType() == QtNode::QT_SOME )
+ {
+ RMInit::logOut << "> rule (condenser order): ALL_CELLS OR SOME_CELLS -> SOME_CELLS OR ALL_CELLS" << endl;
+
+ // order condenser expressions
+
+ QtOperation* node1 = getInput1();
+ QtOperation* node2 = getInput2();
+
+ setInput1( node2 );
+ setInput2( node1 );
+ };
+ }
+ else
+ RMInit::logOut << "Error: QtOr::rewriteOps() - the operand branch is invalid." << endl;
+}
+*/
+
+QtData*
+QtOr::evaluate( QtDataList* inputList )
+{
+ /*
+ // RUNTIME OPTIMIZATION: TRUE OR A -> MDD(TRUE)
+ // A OR TRUE -> MDD(TRUE)
+ // FALSE OR A -> A
+ // A OR FALSE -> A
+ */
+
+ QtData* returnValue = NULL;
+
+ if( input1->getDataStreamType().getDataType() == QT_BOOL &&
+ input2->getDataStreamType().getDataType() == QT_BOOL )
+ {
+ // RUNTIME OPTIMIZATION: FALSE OR A -> A
+ // TRUE OR A -> TRUE
+
+ QtData* operand1=NULL;
+
+ if( getOperand( inputList, operand1, 1 ) )
+ {
+ bool op1 = ((QtAtomicData*)operand1)->getUnsignedValue();
+
+ if( !op1 )
+ {
+ // first operand is obsolete
+ if( operand1 ) operand1->deleteRef();
+
+ QtData* operand2=NULL;
+
+ if( getOperand( inputList, operand2, 2 ) )
+ {
+ returnValue = operand2;
+ }
+ }
+ else
+ {
+ returnValue = operand1;
+ RMDBGONCE(1, RMDebug::module_qlparser, "QtOr", " -> TRUE OR A evaluates TRUE")
+ }
+ }
+ }
+ else
+ returnValue = QtBinaryInduce::evaluate( inputList );
+
+ return returnValue;
+}
+
+
+void
+QtOr::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtOr Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+void
+QtOr::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " or ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtXor::nodeType = QT_XOR;
+
+
+QtXor::QtXor( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_XOR )
+{
+}
+
+/*
+void
+QtXor::checkIdempotency()
+{
+ RMDBGENTER(1, RMDebug::module_qlparser, "QtXor", "enter Xor::checkIdempotency()" )
+
+ if( input1->getSpelling().compare( input2->getSpelling() ) == 0 )
+ {
+ RMInit::logOut << "> rule (idempotency): A XOR A -> FALSE" << endl;
+
+ getParent()->setInput( this, new QtConst( new QtAtomicData( 0 ) ) );
+
+ // delete the node itself and its descendants
+ delete this;
+ };
+
+ RMDBGEXIT(1, RMDebug::module_qlparser, "QtXor", "exit Xor::checkIdempotency()" )
+}
+*/
+
+void
+QtXor::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtXor Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+void
+QtXor::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " xor ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtEqual::nodeType = QT_EQUAL;
+
+QtEqual::QtEqual( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_EQUAL )
+{
+}
+
+/*
+void
+QtEqual::checkIdempotency()
+{
+ if( input1->getSpelling().compare( input2->getSpelling() ) == 0 )
+ {
+ RMInit::logOut << "> rule (idempotency): A == A -> TRUE" << endl;
+
+ getParent()->setInput( this, new QtConst( new QtAtomicData( 1 ) ) );
+
+ // delete the node itself and its descendants
+ delete this;
+ };
+}
+*/
+
+
+void
+QtEqual::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtEqual Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+
+void
+QtEqual::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " = ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtLess::nodeType = QT_LESS;
+
+
+QtLess::QtLess( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_LESS )
+{
+}
+
+
+bool
+QtLess::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+void
+QtLess::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtLess Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+
+void
+QtLess::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " < ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtLessEqual::nodeType = QT_LESS_EQUAL;
+
+
+QtLessEqual::QtLessEqual( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_LESSEQUAL )
+{
+}
+
+
+bool
+QtLessEqual::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+void
+QtLessEqual::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtLessEqual Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+void
+QtLessEqual::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " <= ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtNotEqual::nodeType = QT_NOT_EQUAL;
+
+QtNotEqual::QtNotEqual( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_NOTEQUAL )
+{
+}
+
+/*
+void
+QtNotEqual::checkIdempotency()
+{
+ if( input1->getSpelling().compare( input2->getSpelling() ) == 0 )
+ {
+ RMInit::logOut << "> rule (idempotency): A != A -> FALSE" << endl;
+
+ getParent()->setInput( this, new QtConst( new QtAtomicData( 0 ) ) );
+
+ // delete the node itself and its descendants
+ delete this;
+ };
+}
+*/
+
+void
+QtNotEqual::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtNotEqual Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+
+void
+QtNotEqual::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " != ";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+
+
+const QtNode::QtNodeType QtOverlay::nodeType = QT_OVERLAY;
+
+QtOverlay::QtOverlay( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryInduce( initInput1, initInput2, Ops::OP_OVERLAY )
+{
+}
+
+/*
+void QtOverlay::checkIdempotency()
+{
+}
+*/
+
+
+bool QtOverlay::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+void
+QtOverlay::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtOverlay Object " << getNodeType() << endl;
+
+ QtBinaryInduce::printTree( tab, s, mode );
+}
+
+
+
+void
+QtOverlay::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << " overlay ";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+/********************************************************
+ * QtBit
+ ********************************************************
+ */
+
+
+const QtNode::QtNodeType QtBit::nodeType = QT_BIT;
+
+QtBit::QtBit(QtOperation* initInput1, QtOperation* initInput2)
+ : QtBinaryInduce(initInput1, initInput2, Ops::OP_BIT) {}
+
+
+bool QtBit::isCommutative() const {
+ return false;
+}
+
+void QtBit::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtBit Object " << getNodeType() << endl;
+ QtBinaryInduce::printTree(tab, s, mode);
+}
+
+void QtBit::printAlgebraicExpression(ostream& s) {
+ s << "(";
+
+ if( input2 )
+ input2->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+
+ s << " bit ";
+
+ if( input1 )
+ input1->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+const QtTypeElement& QtBit::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtBit", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType(QT_TYPE_UNKNOWN);
+
+ // check operand branches
+ if(input1 && input2)
+ {
+
+ // get input types
+ const QtTypeElement& inputType1 = input1->checkType(typeTuple);
+ const QtTypeElement& inputType2 = input2->checkType(typeTuple);
+
+ if(RManDebug >= 4) {
+ RMInit::dbgOut << "Operand 1: " << flush;
+ inputType1.printStatus( RMInit::dbgOut );
+ RMInit::dbgOut << endl;
+
+ RMInit::dbgOut << "Operand 2: " << flush;
+ inputType2.printStatus( RMInit::dbgOut );
+ RMInit::dbgOut << endl;
+
+ RMDBGONCE( 4, RMDebug::module_qlparser, "QtBit", "Operation " << opType )
+ }
+
+ if(inputType2.getDataType() < QT_BOOL || inputType2.getDataType() > QT_LONG) {
+ RMInit::logOut << "Error: QtBit::checkType() - second operand must be of integral type." << endl;
+ parseInfo.setErrorNo(418);
+ throw parseInfo;
+ }
+
+ if(inputType1.getDataType() == QT_MDD) {
+ const BaseType* baseType1 = ((MDDBaseType*)(inputType1.getType()))->getBaseType();
+ BaseType* baseType2 = (BaseType*)(inputType2.getType());
+
+ const BaseType* resultBaseType = Ops::getResultType(opType, baseType1, baseType2);
+
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtBit::checkType() - unary induce: operand types are incompatible." << endl;
+ parseInfo.setErrorNo(364);
+ throw parseInfo;
+ }
+
+ MDDBaseType* resultMDDType = new MDDBaseType("tmp", resultBaseType);
+ TypeFactory::addTempType(resultMDDType);
+
+ dataStreamType.setType(resultMDDType);
+ }
+
+ else if(inputType1.isBaseType()) {
+ BaseType* baseType1 = (BaseType*)(inputType1.getType());
+ BaseType* baseType2 = (BaseType*)(inputType2.getType());
+
+ const BaseType* resultBaseType = Ops::getResultType(opType, baseType1, baseType2);
+
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtBit::computeOp() - operand types are incompatible." << endl;
+ parseInfo.setErrorNo(365);
+ throw parseInfo;
+ }
+
+ dataStreamType.setType(resultBaseType);
+ }
+ else {
+ RMInit::logOut << "Error: QtBit::checkType() - operation is not supported on these data types." << endl;
+ parseInfo.setErrorNo(403);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtBit::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
diff --git a/qlparser/qtbinaryinduce2.hh b/qlparser/qtbinaryinduce2.hh
new file mode 100644
index 0000000..96928fb
--- /dev/null
+++ b/qlparser/qtbinaryinduce2.hh
@@ -0,0 +1,358 @@
+#ifndef _QTBINARY2INDUCE_
+#define _QTBINARY2INDUCE_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtbinaryinduce.hh"
+
+#include "catalogmgr/ops.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtIs : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtIs( QtOperation* input1, QtOperation* input2 );
+
+ /// check idempetency rules
+// virtual void checkIdempotency();
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtAnd : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtAnd( QtOperation* input1, QtOperation* input2 );
+
+ /// heuristic ordering of operands
+// virtual void rewriteOps();
+
+ /// check idempetency rules
+// virtual void checkIdempotency();
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtOr : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtOr( QtOperation* input1, QtOperation* input2 );
+
+ /// heuristic ordering of operands
+// virtual void rewriteOps();
+
+ /// check idempetency rules
+ // virtual void checkIdempotency();
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtXor : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtXor( QtOperation* input1, QtOperation* input2 );
+
+ /// check idempetency rules
+// virtual void checkIdempotency();
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtEqual : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtEqual( QtOperation* input1, QtOperation* input2 );
+
+ /// check idempetency rules
+// virtual void checkIdempotency();
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtLess : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtLess( QtOperation* input1, QtOperation* input2 );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// returns false saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtLessEqual : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtLessEqual( QtOperation* input1, QtOperation* input2 );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// returns false saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtNotEqual : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtNotEqual( QtOperation* input1, QtOperation* input2 );
+
+ /// check idempetency rules
+// virtual void checkIdempotency();
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtOverlay : public QtBinaryInduce
+{
+ public:
+ /// constructor getting the two operands
+ QtOverlay( QtOperation* input1, QtOperation* input2 );
+
+ /// check idempetency rules
+// virtual void checkIdempotency();
+
+ /// check commutativity
+ bool isCommutative() const;
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+class QtBit : public QtBinaryInduce {
+public:
+ /// constructor getting the two operands
+ QtBit( QtOperation* input1, QtOperation* input2 );
+
+ /// check commutativity
+ bool isCommutative() const;
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// checkType
+ const QtTypeElement& checkType( QtTypeTuple* typeTuple );
+
+private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+#include "qlparser/qtbinaryinduce2.icc"
+
+#endif
+
diff --git a/qlparser/qtbinaryinduce2.icc b/qlparser/qtbinaryinduce2.icc
new file mode 100644
index 0000000..134b2ea
--- /dev/null
+++ b/qlparser/qtbinaryinduce2.icc
@@ -0,0 +1,95 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtIs::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtAnd::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtOr::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtXor::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtEqual::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtLess::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtLessEqual::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtNotEqual::getNodeType() const
+{
+ return nodeType;
+}
+
+inline const QtNode::QtNodeType
+QtOverlay::getNodeType() const
+{
+ return nodeType;
+}
+
+inline const QtNode::QtNodeType
+QtBit::getNodeType() const
+{
+ return nodeType;
+}
diff --git a/qlparser/qtbinaryoperation.cc b/qlparser/qtbinaryoperation.cc
new file mode 100644
index 0000000..ed05b79
--- /dev/null
+++ b/qlparser/qtbinaryoperation.cc
@@ -0,0 +1,432 @@
+/*
+* 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, QtBinaryOperation: $Id: qtbinaryoperation.cc,v 1.25 2002/04/12 09:51:53 coman Exp $";
+
+#include "qlparser/qtbinaryoperation.hh"
+#include "qlparser/qtconst.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+// constructors
+
+QtBinaryOperation::QtBinaryOperation() :
+ QtOperation(),
+ input1(NULL),
+ input2(NULL)
+{
+}
+
+
+QtBinaryOperation::QtBinaryOperation( QtNode* node ) :
+ QtOperation( node ),
+ input1(NULL),
+ input2(NULL)
+{
+}
+
+
+QtBinaryOperation::QtBinaryOperation( QtOperation* initInput1, QtOperation* initInput2 ) :
+ QtOperation(),
+ input1( initInput1 ),
+ input2( initInput2 )
+{
+ if ( input1 )
+ input1->setParent( this );
+
+ if ( input2 )
+ input2->setParent( this );
+}
+
+// destructor
+
+QtBinaryOperation::~QtBinaryOperation()
+{
+ if ( input1 )
+ {
+ delete input1;
+ input1=NULL;
+ }
+ if ( input2 )
+ {
+ delete input2;
+ input2=NULL;
+ }
+}
+
+
+// pre-evaluate the operation if the nodes contain constant data
+
+void
+QtBinaryOperation::simplify()
+{
+ RMDBCLASS( "QtBinaryOperation", "simplify()", "qlparser", __FILE__, __LINE__ )
+
+ // In order to work bottom up, first inspect the descendants
+ QtNode::simplify();
+
+ // Test, if both operands are available.
+ if( input1 && input2 )
+ {
+ // Test, if both operands are of const type.
+ if( input1->getNodeType() == QT_CONST && input2->getNodeType() == QT_CONST )
+ {
+ // evaluate the self node with no input list
+ QtData* newConst = this->evaluate( NULL );
+
+ if( newConst )
+ {
+ // create a new constant node and fill it with newConst
+ QtConst* newNode = new QtConst( newConst );
+
+ // set its data stream type
+ newNode->checkType( NULL );
+
+ // link it to the parent
+ getParent()->setInput( this, newNode );
+
+ // delete the self node and its descendants
+ delete this;
+ }
+ }
+ }
+
+}
+
+
+// compare this to another node
+
+bool
+QtBinaryOperation::equalMeaning( QtNode* node )
+{
+ RMDBCLASS( "QtBinaryOperation", "equalMeaning( QtNode* )", "qlparser", __FILE__, __LINE__ )
+
+ bool result = false;
+
+ // are the nodes of the same type?
+ if ( getNodeType() == node->getNodeType() )
+ {
+ QtBinaryOperation* binNode = (QtBinaryOperation *) node; // by force
+
+ if ( input1 && input2 ) {
+ if ( isCommutative() )
+ // operation is commutative
+ result = ( input1->equalMeaning( binNode->getInput1() ) &&
+ input2->equalMeaning( binNode->getInput2() ) ) ||
+ ( input1->equalMeaning( binNode->getInput2() ) &&
+ input2->equalMeaning( binNode->getInput1() ) );
+ else
+ // not commutative
+ result = input1->equalMeaning( binNode->getInput1() ) &&
+ input2->equalMeaning( binNode->getInput2() );
+ };
+ };
+
+ return result;
+}
+
+
+// get childs
+
+QtNode::QtNodeList*
+QtBinaryOperation::getChilds( QtChildType flag )
+{
+ RMDBCLASS( "QtBinaryOperation", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
+
+ QtNodeList* resultList = new QtNodeList();
+
+ if ( flag == QT_LEAF_NODES || flag == QT_ALL_NODES ) {
+ QtNodeList* subList=NULL;
+
+ if ( input1 ) {
+ subList = input1->getChilds( flag );
+ resultList->splice(resultList->begin(), *subList);
+ delete subList;
+ subList=NULL;
+ };
+
+ if ( input2 ) {
+ subList = input2->getChilds( flag );
+ resultList->splice(resultList->begin(), *subList);
+ delete subList;
+ subList=NULL;
+ };
+ };
+
+ if ( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES ) {
+ if ( input1 )
+ resultList->push_back( input1 );
+ if ( input2 )
+ resultList->push_back( input2 );
+ };
+
+ return resultList;
+}
+
+
+// get the two operands
+
+bool
+QtBinaryOperation::getOperands( QtDataList* inputList, QtData* &operand1, QtData* &operand2 )
+{
+ RMDBCLASS( "QtBinaryOperation", "getOperands( QtDataList*, QtData*, QtData* )", "qlparser", __FILE__, __LINE__ )
+
+ bool success = false;
+
+ // get the operands
+ try {
+ if ( input1 ) operand1 = input1->evaluate( inputList );
+ if ( input2 ) operand2 = input2->evaluate( inputList );
+ }
+ catch(...)
+ {
+ //clean up code
+ if( operand1 ) {
+ operand1->deleteRef();
+ operand1 = NULL;
+ }
+
+ if( operand2 ){
+ operand2->deleteRef();
+ operand2 = NULL;
+ }
+
+ throw;
+ }
+
+ // test if the operands are valid
+ success = operand1 && operand2;
+
+ if( !success )
+ {
+
+ if( operand1 )
+ {
+ operand1->deleteRef();
+ operand1 = NULL;
+ }
+
+ if( operand2 )
+ {
+ operand2->deleteRef();
+ operand2 = NULL;
+ }
+
+ RMDBGONCE( 1, RMDebug::module_qlparser, "QtBinaryOperation", "Error: QtBinaryOperation::getOperands() - at least one operand is not provided." )
+
+ }
+
+ return success;
+}
+
+
+// get the first or the second operand
+
+bool
+QtBinaryOperation::getOperand( QtDataList* inputList, QtData* &operand, int number )
+{
+ RMDBCLASS( "QtBinaryOperation", "getOperand( QtDataList*, QtData*, int )", "qlparser", __FILE__, __LINE__ )
+
+ bool success = false;
+
+ // get the operand
+ if ( number == 1 ) {
+ if ( input1 ) {
+ operand = input1->evaluate( inputList );
+ } else {
+ if ( input2 )
+ operand = input2->evaluate( inputList );
+ }
+ } else {
+ if ( input2 )
+ operand = input2->evaluate( inputList );
+ }
+
+ // test if the operands are valid
+ if ( operand )
+ success = true;
+ else {
+ RMDBGONCE( 1, RMDebug::module_qlparser, "QtBinaryOperation", "Error: QtBinaryOperation::getOperand() - operand is not provided." )
+ }
+
+ return success;
+}
+
+
+// get spelling
+
+string
+QtBinaryOperation::getSpelling()
+{
+ char tempStr[20];
+ sprintf(tempStr, "%ud", (unsigned long)getNodeType());
+ string result = string(tempStr);
+ result.append( "(" );
+
+ if ( input1 && input2 ) {
+ string result1 = input1->getSpelling();
+ string result2 = input2->getSpelling();
+
+ if( result1.compare( result2 ) < 0 || !isCommutative() )
+ {
+ result.append( result1 );
+ result.append( "," );
+ result.append( result2 );
+ }
+ else
+ {
+ result.append( result2 );
+ result.append( "," );
+ result.append( result1 );
+ };
+ };
+
+ result.append( ")" );
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtBinaryOperation", "Result:" << result.c_str())
+ return result;
+}
+
+
+// get area type
+
+QtNode::QtAreaType
+QtBinaryOperation::getAreaType()
+{
+ QtNode::QtAreaType result = QT_AREA_MDD;
+
+ if ( input1 && input2 )
+ if ( input1->getAreaType() == QtNode::QT_AREA_SCALAR &&
+ input2->getAreaType() == QtNode::QT_AREA_SCALAR )
+ result = QT_AREA_SCALAR;
+
+ return result;
+}
+
+
+// idempotent
+
+/*
+void
+QtBinaryOperation::checkIdempotency()
+{
+}
+*/
+
+// optimize load
+
+void
+QtBinaryOperation::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtBinaryOperation", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtNode::QtTrimList *list1=NULL;
+ QtNode::QtTrimList *list2=NULL;
+
+ if( input1 && input2 )
+ {
+ list1 = trimList;
+
+ // for list2 make a copy of list1
+ list2 = new QtNode::QtTrimList();
+
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ QtTrimElement* elem = new QtTrimElement;
+ *elem = **iter;
+ list2->push_back( elem );
+ }
+
+ if ( input1 )
+ input1->optimizeLoad( list1 );
+
+ if ( input2 )
+ input2->optimizeLoad( list2 );
+
+ }
+ else
+ {
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+ }
+}
+
+
+void
+QtBinaryOperation::printTree( int tab, ostream& s, QtChildType mode )
+{
+ if( mode != QT_DIRECT_CHILDS )
+ {
+ if( input1 )
+ {
+ s << SPACE_STR(tab).c_str() << "input1: " << endl;
+ input1->printTree( tab+2, s, mode );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no input1" << endl;
+
+ if( input2 )
+ {
+ s << SPACE_STR(tab).c_str() << "input2: " << endl;
+ input2->printTree( tab+2, s, mode );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no input2" << endl;
+ }
+}
+
+
+
+bool
+QtBinaryOperation::isCommutative() const
+{
+ return true; // by default, a binary operation is commutative
+}
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtbinaryoperation.hh b/qlparser/qtbinaryoperation.hh
new file mode 100644
index 0000000..cf15666
--- /dev/null
+++ b/qlparser/qtbinaryoperation.hh
@@ -0,0 +1,150 @@
+#ifndef _QTBINARYOPERATION_
+#define _QTBINARYOPERATION_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include <stdio.h>
+
+#include "qlparser/qtoperation.hh"
+
+/*
+* 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>.
+*/
+/**************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+The class serves as superclass for all operation classes taking two
+arguments.
+
+*/
+
+class QtBinaryOperation : public QtOperation
+{
+ public:
+ /// default constructor
+ QtBinaryOperation();
+
+ /// constructor getting the node to the parent
+ QtBinaryOperation( QtNode* node );
+
+ /// constructor getting pointers to its operands
+ QtBinaryOperation( QtOperation* input1, QtOperation* input2 );
+
+ /// virtual destructor
+ virtual ~QtBinaryOperation();
+
+ /// simplifies the tree
+ virtual void simplify();
+
+ /// test if the two nodes have an equal meaning in the query tree
+ virtual bool equalMeaning( QtNode* node );
+ /**
+ The meaning of a binary operation is equal, iff both operands have
+ the same meaning. In case of a commutative operation, the operands
+ can be switched.
+ */
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// creates a unique name for a subexpression
+ virtual std::string getSpelling();
+
+ /// test if the edge to the parent node is of type mdd or atomic
+ virtual QtAreaType getAreaType();
+
+ /// method for query rewrite
+ inline virtual void setInput( QtOperation* inputOld, QtOperation* inputNew );
+
+ /// method for checking idempotency rules
+// virtual void checkIdempotency();
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+ /**
+ The method deletes the given {\tt trimList} and passes the {\tt optimizeLoad}
+ message with empty triming lists to its input trees. The method is rewritten
+ by some subclasses.
+ */
+
+ /// debugging method
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ //@Man: read/write methods for the operands
+ //@{
+ ///
+ ///
+ inline void setInput1( QtOperation* input );
+ ///
+ inline void setInput2( QtOperation* input );
+ ///
+ inline QtOperation* getInput1();
+ ///
+ inline QtOperation* getInput2();
+ ///
+ //@}
+
+ /// returns commutativity information (by default, an operation IS commutative)
+ virtual bool isCommutative() const;
+
+ protected:
+ /// method for testing and evaluating the input branches
+ bool getOperands( QtDataList* inputList, QtData* &operand1, QtData* &operand2 );
+ /**
+ The method checks if the input branches are valid. Then it passes the evaluate message to its two
+ operands with the {\tt inputList} as argument. The returned results are provided through the arguments
+ {\tt operand1} and {\tt operand2} called by reference. The method returns {\tt true} it the operands are
+ valid, otherwise {\tt false}.
+ */
+
+ /// method for testing and evaluating the input branches
+ bool getOperand( QtDataList* inputList, QtData* &operand1, int number);
+ /**
+ The method checks if the by number specified input branch si valid. Then it passes the evaluate message to the
+ operand with the {\tt inputList} as argument. The returned result are provided through the argument
+ {\tt operand} called by reference. The method returns {\tt true} it the operand is
+ valid, otherwise {\tt false}.
+ */
+
+ /// first operation operand
+ QtOperation* input1;
+ /// second operation operand
+ QtOperation* input2;
+};
+
+#include "qlparser/qtbinaryoperation.icc"
+
+#endif
+
+
diff --git a/qlparser/qtbinaryoperation.icc b/qlparser/qtbinaryoperation.icc
new file mode 100644
index 0000000..7cb55cb
--- /dev/null
+++ b/qlparser/qtbinaryoperation.icc
@@ -0,0 +1,89 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline void
+QtBinaryOperation::setInput1( QtOperation* input )
+{
+ input1 = input;
+
+ if( input )
+ input->setParent( this );
+};
+
+
+
+inline void
+QtBinaryOperation::setInput2( QtOperation* input )
+{
+ input2 = input;
+
+ if( input )
+ input->setParent( this );
+};
+
+
+
+inline QtOperation*
+QtBinaryOperation::getInput1()
+{
+ return input1;
+};
+
+
+
+inline QtOperation*
+QtBinaryOperation::getInput2()
+{
+ return input2;
+};
+
+
+
+inline void
+QtBinaryOperation::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ if( inputOld == input1 )
+ {
+ setInput1( inputNew );
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+
+ if( inputOld == input2 )
+ {
+ setInput2( inputNew );
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+};
+
+
+
diff --git a/qlparser/qtcommand.cc b/qlparser/qtcommand.cc
new file mode 100644
index 0000000..3574519
--- /dev/null
+++ b/qlparser/qtcommand.cc
@@ -0,0 +1,182 @@
+/*
+* 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, QtCommand: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtcommand.cc,v 1.21 2005/09/03 20:17:55 rasdev Exp $";
+
+#include "qlparser/qtcommand.hh"
+#include "mddmgr/mddcoll.hh"
+#include "catalogmgr/typefactory.hh"
+#include "reladminif/databaseif.hh"
+#include "relcatalogif/settype.hh"
+#include "servercomm/servercomm.hh"
+
+#include <iostream>
+
+
+extern ServerComm::ClientTblElt* currentClientTblElt;
+
+const QtNode::QtNodeType QtCommand::nodeType = QtNode::QT_COMMAND;
+
+
+
+QtCommand::QtCommand( QtCommandType initCommand, const std::string& initCollection, const std::string& initType )
+ : QtExecute(),
+ command( initCommand ),
+ collectionName( initCollection ),
+ typeName( initType )
+{
+}
+
+
+
+QtCommand::QtCommand( QtCommandType initCommand, const std::string& initCollection )
+ : QtExecute(),
+ command( initCommand ),
+ collectionName( initCollection )
+{
+}
+
+
+
+int
+QtCommand::evaluate()
+{
+ RMDBGENTER(2, RMDebug::module_qlparser, "QtCommand", "evaluate()")
+
+ switch( command )
+ {
+ case QT_DROP_COLLECTION:
+ if( currentClientTblElt )
+ if (!MDDColl::dropMDDCollection(collectionName.c_str()))
+ {
+ RMInit::logOut << "Error during query evaluation: collection name not found: " << collectionName.c_str() << std::endl;
+ parseInfo.setErrorNo(957);
+ throw parseInfo;
+ }
+ break;
+ case QT_CREATE_COLLECTION:
+ if( currentClientTblElt )
+ {
+ // get collection type
+ CollectionType* collType = (CollectionType*)TypeFactory::mapSetType( (char*)typeName.c_str() );
+
+ if( collType )
+ {
+ // allocate a new oid within the current db
+ OId oid;
+#ifdef BASEDB_O2
+ if( !OId::allocateMDDCollOId( &oid ) )
+ {
+#else
+ OId::allocateOId(oid, OId::MDDCOLLOID);
+#endif
+ try
+ {
+ MDDColl* coll = MDDColl::createMDDCollection(collectionName.c_str(), oid, collType);
+ delete coll;
+ coll=NULL;
+ }
+ catch( r_Error& obj )
+ {
+ RMInit::logOut << "Error during query evaluation: collection name exists already: " << collectionName.c_str() << std::endl;
+ if (obj.get_kind() != r_Error::r_Error_NameNotUnique)
+ RMInit::logOut << "Exception: " << obj.what() << std::endl;;
+ parseInfo.setErrorNo(955);
+ throw parseInfo;
+ }
+#ifdef BASEDB_O2
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtCommand::evaluate() - oid allocation failed" << std::endl;
+ parseInfo.setErrorNo(958);
+ throw parseInfo;
+ }
+#endif
+ }
+ else
+ {
+ RMInit::logOut << "Error during query evaluation: collection type not found: " << (char*)typeName.c_str() << std::endl;
+ parseInfo.setErrorNo(956);
+ throw parseInfo;
+ }
+ break;
+ }
+ }
+
+ RMDBGEXIT(2, RMDebug::module_qlparser, "QtCommand", "evaluate()")
+
+ return 0;
+}
+
+
+
+void
+QtCommand::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtCommand Object" << std::endl;
+
+ switch( command )
+ {
+ case QT_DROP_COLLECTION: s << SPACE_STR(tab).c_str() << " drop collection(" << collectionName.c_str() << ")"; break;
+ case QT_CREATE_COLLECTION: s << SPACE_STR(tab).c_str() << " create collection(" << collectionName.c_str() << ", " << typeName.c_str() <<")"; break;
+ default: s << "<command unknown>";
+ }
+
+ s << std::endl;
+}
+
+
+
+void
+QtCommand::printAlgebraicExpression( std::ostream& s )
+{
+ s << "command<";
+
+ switch( command )
+ {
+ case QT_DROP_COLLECTION: s << "drop collection(" << collectionName.c_str() << ")"; break;
+ case QT_CREATE_COLLECTION: s << "create collection(" << collectionName.c_str() << ", " << typeName.c_str() <<")"; break;
+ default: s << "unknown";
+ }
+
+ s << ">";
+}
+
+
+
+void
+QtCommand::checkType()
+{
+ // nothing to do here
+}
+
diff --git a/qlparser/qtcommand.hh b/qlparser/qtcommand.hh
new file mode 100644
index 0000000..76c4375
--- /dev/null
+++ b/qlparser/qtcommand.hh
@@ -0,0 +1,97 @@
+#ifndef __QTCOMMAND_HH__
+#define __QTCOMMAND_HH___
+
+#include "qlparser/qtexecute.hh"
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+#include <iostream>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/**
+
+*/
+
+class QtCommand : public QtExecute
+{
+ public:
+ enum QtCommandType
+ {
+ QT_DROP_COLLECTION,
+ QT_CREATE_COLLECTION
+ };
+
+ /// constructor getting command, collection and type name (create collection)
+ QtCommand( QtCommandType initCommand, const std::string& initCollection, const std::string& initType );
+
+ /// constructor getting command and collection name (drop collection)
+ QtCommand( QtCommandType initCommand, const std::string& initCollection );
+
+ /// method for evaluating the node
+ virtual int evaluate();
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking
+ virtual void checkType();
+
+ private:
+ /// command type
+ QtCommandType command;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+
+ /// collection name for drop/create collection
+ std::string collectionName;
+
+ /// type name for create collection
+ std::string typeName;
+};
+
+#include "qlparser/qtcommand.icc"
+
+#endif
+
+
+
diff --git a/qlparser/qtcommand.icc b/qlparser/qtcommand.icc
new file mode 100644
index 0000000..cb8353b
--- /dev/null
+++ b/qlparser/qtcommand.icc
@@ -0,0 +1,35 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtCommand::getNodeType() const
+{
+ return nodeType;
+}
+
diff --git a/qlparser/qtcomplexdata.cc b/qlparser/qtcomplexdata.cc
new file mode 100644
index 0000000..36a822d
--- /dev/null
+++ b/qlparser/qtcomplexdata.cc
@@ -0,0 +1,109 @@
+/*
+* 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, QtComplexData: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtcomplexdata.cc,v 1.12 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtcomplexdata.hh"
+#include "relcatalogif/structtype.hh"
+#include <stdio.h>
+#include <cstring>
+
+QtComplexData::QtComplexData()
+ : QtScalarData()
+{
+}
+
+
+
+QtComplexData::QtComplexData( QtComplexData::QtScalarDataList* &scalarDataList )
+ : QtScalarData()
+{
+ char elementName[256];
+ unsigned int i=0;
+ std::list<QtScalarData*>::iterator iter;
+
+ // Take care of dynamic memory management:
+ //
+ // Types, which are not in the typeFactory, have to be deleted. This means that, in general,
+ // all complex types have to be deleted because they are constructed temporarily.
+
+ // create a new struct type
+ StructType* structType = new StructType( "", scalarDataList->size() );
+
+ // add type elements, the first element inserted has no 0, the second no 1, and so on
+ for( iter=scalarDataList->begin(), i=0; iter!=scalarDataList->end(); iter++, i++ )
+ {
+ sprintf( elementName, "%d", i );
+ structType->addElement( elementName, (*iter)->getValueType() );
+ }
+
+ // add type to typeFactory
+ TypeFactory::addTempType( structType );
+
+ valueBuffer = new char[ structType->getSize() ];
+ valueType = structType;
+
+ // copy data
+ for( iter=scalarDataList->begin(), i=0; iter!=scalarDataList->end(); iter++, i++ )
+ {
+ char* destination = ((char*)valueBuffer) + structType->getOffset( i );
+
+ memcpy( (void*)destination, (void*)((*iter)->getValueBuffer()), (*iter)->getValueType()->getSize() );
+ }
+
+ // delete the list of type elements
+ // release( scalarDataList->begin(), scalarDataList->end() );
+ for( iter=scalarDataList->begin(); iter!=scalarDataList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete scalarDataList;
+ scalarDataList = NULL;
+}
+
+
+
+QtComplexData::QtComplexData( const QtComplexData& obj )
+ : QtScalarData( obj )
+{
+}
+
+
+
+void
+QtComplexData::printStatus( ostream& stream ) const
+{
+ stream << "complex, " << std::flush;
+ QtScalarData::printStatus( stream );
+ stream << std::endl;
+}
diff --git a/qlparser/qtcomplexdata.hh b/qlparser/qtcomplexdata.hh
new file mode 100644
index 0000000..51178b8
--- /dev/null
+++ b/qlparser/qtcomplexdata.hh
@@ -0,0 +1,92 @@
+#ifndef _QTCOMPLEXDATA_HH
+#define _QTCOMPLEXDATA_HH
+
+#include "qlparser/qtscalardata.hh"
+
+#include <list>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/**
+
+ The class represents a complex scalar value handled by the query tree.
+
+*/
+
+class QtComplexData : public QtScalarData
+{
+ public:
+ /// list of \Ref{QtScalarData} objects
+ typedef std::list<QtScalarData*> QtScalarDataList;
+
+ /// default constructor
+ QtComplexData();
+
+ /// constructor getting a pointer to a list of \Ref{QtScalarData} objects
+ QtComplexData( QtScalarDataList* &scalarDataList );
+ /**
+ Construct an object with \Ref{QtScalarData} elements of the list and
+ destroy the list afterwards. {\ttscalarDataList} is set to zero.
+ */
+
+ /// copy constructor
+ QtComplexData( const QtComplexData& obj );
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+};
+
+#include "qlparser/qtcomplexdata.icc"
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtcomplexdata.icc b/qlparser/qtcomplexdata.icc
new file mode 100644
index 0000000..2651f9c
--- /dev/null
+++ b/qlparser/qtcomplexdata.icc
@@ -0,0 +1,29 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
diff --git a/qlparser/qtcondense.cc b/qlparser/qtcondense.cc
new file mode 100644
index 0000000..7a17b93
--- /dev/null
+++ b/qlparser/qtcondense.cc
@@ -0,0 +1,801 @@
+/*
+* 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, QtCondense: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtcondense.cc,v 1.47 2005/09/03 20:17:55 rasdev Exp $";
+
+#include "raslib/rmdebug.hh"
+#include "debug.hh"
+
+#include "qlparser/qtcondense.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtscalardata.hh"
+#include "qlparser/qtcomplexdata.hh"
+#include "qlparser/qtbinaryinduce.hh"
+#include "qlparser/qtbinaryinduce2.hh"
+
+#include "mddmgr/mddobj.hh"
+
+#include "catalogmgr/typefactory.hh"
+#include "catalogmgr/ops.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+const QtNode::QtNodeType QtCondense::nodeType = QtNode::QT_CONDENSE;
+
+QtCondense::QtCondense( Ops::OpType newOpType )
+ : QtUnaryOperation(), opType( newOpType )
+{
+}
+
+
+
+QtCondense::QtCondense( Ops::OpType newOpType, QtOperation* initInput )
+ : QtUnaryOperation( initInput ), opType( newOpType )
+{
+}
+
+
+QtNode::QtAreaType
+QtCondense::getAreaType()
+{
+ return QT_AREA_SCALAR;
+}
+
+
+
+void
+QtCondense::optimizeLoad( QtTrimList* trimList )
+{
+ // reset trimList because optimization enters a new MDD area
+
+ // delete list
+ // release( trimList->begin(), trimList->end() );
+ vector<QtNode::QtTrimElement*>::iterator iter;
+ for( iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+
+ delete trimList;
+ trimList=NULL;
+
+ if( input )
+ input->optimizeLoad( new QtNode::QtTrimList );
+}
+
+
+
+QtData*
+QtCondense::computeFullCondense( QtDataList* inputList, r_Minterval& areaOp )
+{
+ RMDBCLASS( "QtCondense", "computeFullCondense( QtDataList*, r_Minterval& )", "qlparser", __FILE__, __LINE__ )
+
+ QtScalarData* returnValue = NULL;
+
+ // get the operand
+ QtData* operand = input->evaluate( inputList );
+
+ if( operand )
+ {
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Internal error in QtCountCells::computeFullCondense() - "
+ << "runtime type checking failed (MDD)." << endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ QtMDD* mdd = (QtMDD*)operand;
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( opType == Ops::OP_SOME || opType == Ops::OP_ALL || opType == Ops::OP_COUNT )
+ {
+ if( mdd->getCellType()->getType() != BOOLTYPE )
+ {
+ RMInit::logOut << "Internal error in QtCondense::computeFullCondense() - "
+ << "runtime type checking failed (BOOL)." << endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+ }
+#endif
+
+ // get result type
+ const BaseType* resultType = Ops::getResultType( opType, mdd->getCellType() );
+
+ // get the MDD object
+ MDDObj* op = ((QtMDD*)operand)->getMDDObject();
+
+ // get the area, where the operation has to be applied
+ areaOp = mdd->getLoadDomain();
+
+TALK( "computeFullCondense-last-good\n" );
+ // get all tiles in relevant area
+ vector<Tile*>* allTiles = op->intersect(areaOp);
+
+TALK( "computeFullCondense-8\n" );
+ // get new operation object
+ CondenseOp* condOp = Ops::getCondenseOp( opType, resultType, mdd->getCellType() );
+
+TALK( "computeFullCondense-9\n" );
+ // and iterate over them
+ for( vector<Tile*>::iterator tileIt = allTiles->begin();
+ tileIt!=allTiles->end(); tileIt++ )
+ {
+ // domain of the actual tile
+ r_Minterval tileDom = (*tileIt)->getDomain();
+
+ // domain of the relevant area of the actual tile
+ r_Minterval intersectDom = tileDom.create_intersection( areaOp );
+
+ (*tileIt)->execCondenseOp( condOp, intersectDom );
+ }
+
+ // delete tile vector
+ delete allTiles;
+ allTiles=NULL;
+
+TALK( "computeFullCondense-a\n" );
+ // create result object
+ if( resultType->getType() == STRUCT )
+ returnValue = new QtComplexData();
+ else
+ returnValue = new QtAtomicData();
+
+TALK( "computeFullCondense-b\n" );
+ // allocate buffer for the result
+ char* resultBuffer = new char[resultType->getSize()];
+ memcpy( (void*)resultBuffer, (void*)condOp->getAccuVal(), (size_t)resultType->getSize() );
+
+TALK( "computeFullCondense-c\n" );
+ returnValue->setValueType ( resultType );
+ returnValue->setValueBuffer( resultBuffer );
+
+TALK( "computeFullCondense-d\n" );
+ // delete operation object
+ delete condOp;
+ condOp=NULL;
+
+TALK( "computeFullCondense-e\n" );
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtCondense", \
+ RMInit::dbgOut << endl << "opType of QtCondense::computeFullCondense(): " << opType << endl; \
+ RMInit::dbgOut << "Result.....................................: " << flush; \
+ returnValue->printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; )
+ return returnValue;
+}
+
+
+
+const QtTypeElement&
+QtCondense::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtCondense", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtCondense", \
+ RMInit::dbgOut << "Class..: " << getClassName() << endl; \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; )
+
+ if( inputType.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtCondense::evaluate() - operand must be multidimensional." << endl;
+ parseInfo.setErrorNo(353);
+ throw parseInfo;
+ }
+
+ const BaseType* baseType = ((const MDDBaseType*)(inputType.getType()))->getBaseType();
+
+ if( opType == Ops::OP_SOME || opType == Ops::OP_ALL )
+ {
+ if( baseType->getType() != BOOLTYPE )
+ {
+ RMInit::logOut << "Error: QtCondense::evaluate() - operand of quantifiers must be of type r_Marray<d_Boolean>." << endl;
+ parseInfo.setErrorNo(354);
+ throw parseInfo;
+ }
+ }
+
+ if( opType == Ops::OP_COUNT )
+ {
+ if( baseType->getType() != BOOLTYPE )
+ {
+ RMInit::logOut << "Error: QtCondense::evaluate() - operand of count_cells must be of type r_Marray<d_Boolean>." << endl;
+ parseInfo.setErrorNo(415);
+ throw parseInfo;
+ }
+ }
+
+ const BaseType* resultType = Ops::getResultType( opType, baseType );
+
+ if( getNodeType() == QT_AVGCELLS )
+ {
+ // consider division by the number of cells
+
+ const BaseType* DoubleType = TypeFactory::mapType("Double");
+ const BaseType* finalResultType = Ops::getResultType( Ops::OP_DIV, resultType, DoubleType );
+
+ resultType = finalResultType;
+ }
+
+ dataStreamType.setType( resultType );
+ }
+ else
+ RMInit::logOut << "Error: QtCondense::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
+void
+QtCondense::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << getClassName() << " object" << endl;
+
+ QtUnaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtCondense::printAlgebraicExpression( ostream& s )
+{
+ s << getAlgebraicName() << "(";
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtNode::QtNodeType QtSome::nodeType = QtNode::QT_SOME;
+
+
+QtSome::QtSome()
+ : QtCondense( Ops::OP_SOME )
+{
+}
+
+
+QtSome::QtSome( QtOperation* inputNew )
+ : QtCondense( Ops::OP_SOME, inputNew )
+{
+}
+
+/*
+void
+QtSome::rewriteOps()
+{
+ if( input )
+ {
+ if( input->getNodeType() == QtNode::QT_OR )
+ {
+ // pushdown of condenser expression
+
+ QtOr* orNode = (QtOr*) input;
+ QtOperation* node1 = orNode->getInput1();
+ QtOperation* node2 = orNode->getInput2();
+
+ if( node1 && node2 &&
+ node1->getAreaType() == QtNode::QT_AREA_MDD &&
+ node2->getAreaType() == QtNode::QT_AREA_MDD )
+ {
+ RMInit::logOut << "> rule (pushdown condenser): SOME_CELLS(A OR B) -> SOME_CELLS(A) OR SOME_CELLS(B)" << endl;
+
+ QtSome* newNode = new QtSome( node1 );
+ setInput( node2 );
+ newNode->setDataStreamType( QtTypeElement(QT_BOOL) );
+
+ this->getParent()->setInput( this, orNode );
+ orNode->setInput1( newNode );
+ orNode->setInput2( this );
+ orNode->setDataStreamType( QtTypeElement(QT_BOOL) );
+
+ newNode->rewriteOps();
+ }
+ };
+
+ input->rewriteOps();
+ }
+ else
+ RMInit::logOut << "Error: QtSome::rewriteOps() - the operand branch is invalid." << endl;
+}
+*/
+
+QtData*
+QtSome::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtSome", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ r_ULong dummy=0; // needed for conversion to and from CULong
+
+ // get the operand
+ QtData* operand = input->evaluate( inputList );
+
+ if( operand )
+ {
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Internal error in QtSome::evaluate() - "
+ << "runtime type checking failed (MDD)." << endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ QtMDD* mdd = (QtMDD*)operand;
+
+ // get result type
+ BaseType* resultType = (BaseType*)dataStreamType.getType();
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( mdd->getCellType()->getType() != BOOLTYPE )
+ RMInit::logOut << "Internal error in QtSome::evaluate() - "
+ << "runtime type checking failed (BOOL)." << endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ // get the MDD object
+ MDDObj* op = mdd->getMDDObject();
+
+ // get the area, where the operation has to be applied
+ r_Minterval areaOp = mdd->getLoadDomain();
+
+ // get all tiles in relevant area
+ vector<Tile*>* allTiles = op->intersect(areaOp);
+
+ // allocate buffer for the result
+ unsigned int typeSize = resultType->getSize();
+ char* resultBuffer = new char[typeSize];
+
+ // initialize result buffer with false
+ dummy = 0;
+ resultType->makeFromCULong( resultBuffer, &dummy );
+ CondenseOp* condOp = Ops::getCondenseOp(Ops::OP_SOME, resultType, resultBuffer, resultType, 0, 0);
+
+ // and iterate over them
+ for( vector<Tile*>::iterator tileIt = allTiles->begin(); tileIt != allTiles->end() && !dummy ; tileIt++ )
+ {
+ // domain of the actual tile
+ r_Minterval tileDom = (*tileIt)->getDomain();
+
+ // domain of the relevant area of the actual tile
+ r_Minterval intersectDom = tileDom.create_intersection( areaOp );
+ (*tileIt)->execCondenseOp( condOp, intersectDom );
+ resultType->convertToCULong( condOp->getAccuVal(), &dummy );
+ }
+
+ delete condOp;
+ condOp = NULL;
+ // delete tile vector
+ delete allTiles;
+ allTiles=NULL;
+
+ // create QtAtomicData object for the result
+ returnValue = new QtAtomicData( (bool)(dummy) );
+
+ // delete result buffer
+ delete[] resultBuffer;
+ resultBuffer = NULL;
+
+ // The following is now then when deleting the last reference to the operand.
+ // delete the obsolete MDD object
+ // delete op;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+
+ return returnValue;
+}
+
+
+
+const QtAll::QtNodeType QtAll::nodeType = QtNode::QT_ALL;
+
+
+QtAll::QtAll()
+ : QtCondense( Ops::OP_ALL )
+{
+}
+
+
+QtAll::QtAll( QtOperation* inputNew )
+ : QtCondense( Ops::OP_ALL, inputNew )
+{
+}
+
+/*
+void
+QtAll::rewriteOps()
+{
+ if( input )
+ {
+ if( input->getNodeType() == QtNode::QT_AND )
+ {
+ // pushdown of condenser expression
+
+ QtAnd* andNode = (QtAnd*) input;
+ QtOperation* node1 = andNode->getInput1();
+ QtOperation* node2 = andNode->getInput2();
+
+ if( node1 && node2 &&
+ node1->getAreaType() == QtNode::QT_AREA_MDD &&
+ node2->getAreaType() == QtNode::QT_AREA_MDD )
+ {
+ RMInit::logOut << "> rule (pushdown condenser): ALL_CELLS(A AND B) -> ALL_CELLS(A) AND ALL_CELLS(B)" << endl;
+
+ QtAll* newNode = new QtAll( node1 );
+ setInput( node2 );
+ newNode->setDataStreamType( QtTypeElement(QT_BOOL) );
+
+ this->getParent()->setInput( this, andNode );
+ andNode->setInput1( newNode );
+ andNode->setInput2( this );
+ andNode->setDataStreamType( QtTypeElement(QT_BOOL) );
+
+ newNode->rewriteOps();
+ }
+ };
+
+ input->rewriteOps();
+
+ }
+ else
+ RMInit::logOut << "Error: QtAll::rewriteOps() - the operand branch is invalid." << endl;
+}
+*/
+
+QtData*
+QtAll::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtAll", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ r_ULong dummy=0; // needed for conversion to and from CULong
+
+ // get the operand
+ QtData* operand = input->evaluate( inputList );
+
+ if( operand )
+ {
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Internal error in QtAll::evaluate() - "
+ << "runtime type checking failed (MDD)." << endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ QtMDD* mdd = (QtMDD*)operand;
+
+ // get result type
+ const BaseType* resultType = (BaseType*)dataStreamType.getType();
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( mdd->getCellType()->getType() != BOOLTYPE )
+ RMInit::logOut << "Internal error in QtAll::evaluate() - "
+ << "runtime type checking failed (BOOL)." << endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ // get the MDD object
+ MDDObj* op = ((QtMDD*)operand)->getMDDObject();
+
+ // get the area, where the operation has to be applied
+ r_Minterval areaOp = mdd->getLoadDomain();
+
+ // get all tiles in relevant area
+ vector<Tile*>* allTiles = op->intersect(areaOp);
+
+ // allocate buffer for the result
+ unsigned int tempTypeSize = resultType->getSize();
+ char* resultBuffer = new char[tempTypeSize];
+
+ // initialize result buffer with true
+ dummy = 1;
+ resultType->makeFromCULong( resultBuffer, &dummy );
+ CondenseOp* condOp = Ops::getCondenseOp(Ops::OP_ALL, resultType, resultBuffer, resultType, 0, 0);
+
+ for( std::vector<Tile*>::iterator tileIt = allTiles->begin(); tileIt!=allTiles->end() && dummy; tileIt++ )
+ {
+ // domain of the actual tile
+ r_Minterval tileDom = (*tileIt)->getDomain();
+
+ // domain of the relevant area of the actual tile
+ r_Minterval intersectDom = tileDom.create_intersection( areaOp );
+
+ (*tileIt)->execCondenseOp( condOp, intersectDom );
+ resultType->convertToCULong( condOp->getAccuVal(), &dummy );
+ }
+ delete condOp;
+ condOp = NULL;
+ // delete tile vector
+ delete allTiles;
+ allTiles=NULL;
+
+ // create QtBoolData object for the result
+ returnValue = new QtAtomicData( (bool)(dummy) );
+
+ // delete result buffer done in delete CondOp
+ delete[] resultBuffer;
+ resultBuffer=NULL;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+
+ return returnValue;
+}
+
+
+
+const QtCountCells::QtNodeType QtCountCells::nodeType = QtNode::QT_COUNTCELLS;
+
+
+QtCountCells::QtCountCells()
+ : QtCondense( Ops::OP_COUNT )
+{
+}
+
+
+QtCountCells::QtCountCells( QtOperation* inputNew )
+ : QtCondense( Ops::OP_COUNT, inputNew )
+{
+}
+
+
+QtData*
+QtCountCells::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtCountCells", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+r_Minterval dummyint;
+ QtData* returnValue = QtCondense::computeFullCondense( inputList, dummyint );
+
+ return returnValue;
+}
+
+
+
+const QtAddCells::QtNodeType QtAddCells::nodeType = QtNode::QT_ADDCELLS;
+
+
+QtAddCells::QtAddCells()
+ : QtCondense( Ops::OP_SUM )
+{
+}
+
+
+QtAddCells::QtAddCells( QtOperation* inputNew )
+ : QtCondense( Ops::OP_SUM, inputNew )
+{
+}
+
+
+QtData*
+QtAddCells::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtAddCells", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+r_Minterval dummyint;
+
+ QtData* returnValue = QtCondense::computeFullCondense( inputList, dummyint );
+
+ return returnValue;
+}
+
+
+
+const QtAvgCells::QtNodeType QtAvgCells::nodeType = QtNode::QT_AVGCELLS;
+
+
+QtAvgCells::QtAvgCells()
+ : QtCondense( Ops::OP_SUM )
+{
+}
+
+
+QtAvgCells::QtAvgCells( QtOperation* inputNew )
+ : QtCondense( Ops::OP_SUM, inputNew )
+{
+}
+
+
+QtData*
+QtAvgCells::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtAvgCells", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ // domain for condensing operation
+ r_Minterval areaOp;
+
+ QtData* dataCond = QtCondense::computeFullCondense( inputList, areaOp );
+
+ //
+ // divide by the number of cells
+ //
+
+ QtScalarData* scalarDataResult = NULL;
+ QtScalarData* scalarDataCond = (QtScalarData*)dataCond;
+ BaseType* resultType = (BaseType*)dataStreamType.getType();
+
+
+ // allocate memory for the result
+ char* resultBuffer = new char[ resultType->getSize() ];
+
+ // allocate ulong constant with number of cells
+ r_ULong constValue = areaOp.cell_count();
+ const BaseType* constType = TypeFactory::mapType("ULong");
+ char* constBuffer = new char[ constType->getSize() ];
+
+ constType->makeFromCULong( constBuffer, &constValue );
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtCondense", \
+ RMInit::dbgOut << "Number of cells....: " << flush; \
+ constType->printCell( RMInit::dbgOut, constBuffer ); \
+ RMInit::dbgOut << endl; )
+
+ Ops::execBinaryConstOp( Ops::OP_DIV, resultType,
+ scalarDataCond->getValueType(), constType,
+ resultBuffer,
+ scalarDataCond->getValueBuffer(), constBuffer );
+
+ delete[] constBuffer;
+ constBuffer=NULL;
+ delete dataCond;
+ dataCond=NULL;
+
+ if( resultType->getType() == STRUCT )
+ scalarDataResult = new QtComplexData();
+ else
+ scalarDataResult = new QtAtomicData();
+
+ scalarDataResult->setValueType ( resultType );
+ scalarDataResult->setValueBuffer( resultBuffer );
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtCondense", \
+ RMInit::dbgOut << endl << "Result.............: " << flush; \
+ scalarDataResult->printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; )
+
+ return scalarDataResult;
+}
+
+
+const QtMinCells::QtNodeType QtMinCells::nodeType = QtNode::QT_MINCELLS;
+
+
+QtMinCells::QtMinCells()
+ : QtCondense( Ops::OP_MIN )
+{
+}
+
+
+QtMinCells::QtMinCells( QtOperation* inputNew )
+ : QtCondense( Ops::OP_MIN, inputNew )
+{
+}
+
+
+QtData*
+QtMinCells::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtMinCells", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+r_Minterval dummyint;
+
+ QtData* returnValue = QtCondense::computeFullCondense( inputList, dummyint );
+
+ return returnValue;
+}
+
+
+
+const QtMaxCells::QtNodeType QtMaxCells::nodeType = QtNode::QT_MAXCELLS;
+
+
+QtMaxCells::QtMaxCells()
+ : QtCondense( Ops::OP_MAX )
+{
+}
+
+
+QtMaxCells::QtMaxCells( QtOperation* inputNew )
+ : QtCondense( Ops::OP_MAX, inputNew )
+{
+}
+
+
+QtData*
+QtMaxCells::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtMaxCells", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+r_Minterval dummyint;
+
+ QtData* returnValue = QtCondense::computeFullCondense( inputList, dummyint );
+
+ return returnValue;
+}
diff --git a/qlparser/qtcondense.hh b/qlparser/qtcondense.hh
new file mode 100644
index 0000000..46f2fac
--- /dev/null
+++ b/qlparser/qtcondense.hh
@@ -0,0 +1,352 @@
+#ifndef _QTCONDENSE_
+#define _QTCONDENSE_
+
+#include "qlparser/qtunaryoperation.hh"
+#include "raslib/minterval.hh"
+#include "catalogmgr/ops.hh"
+
+/*
+* 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>.
+*/
+/**************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents a condense operation in the query tree.
+
+*/
+
+class QtCondense : public QtUnaryOperation
+{
+ public:
+ /// constructor getting operation
+ QtCondense( Ops::OpType newOpType);
+
+ /// constructor getting operation and operand
+ QtCondense( Ops::OpType newOpType, QtOperation* input );
+
+ /// method for computing full condense operation (without early termination option)
+ QtData* computeFullCondense( QtDataList* inputList, r_Minterval& areaOp);// = r_Minterval() );
+
+ /// test if the edge to the parent node is of type mdd or atomic
+ virtual QtAreaType getAreaType();
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+ /**
+ The method deletes the given {\tt trimList} and passes the {\tt optimizeLoad}
+ message with empty triming list to its operand tree.
+
+ Optimization process enters a new MDD area.
+ */
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method returning class name
+ inline virtual const char* getClassName() const;
+
+ /// method returning algebraic identifier
+ inline virtual const char* getAlgebraicName() const;
+
+ protected:
+ /// operation type
+ Ops::OpType opType;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the specialized condenser {\tt some_cells()} in the query tree.
+
+*/
+
+class QtSome : public QtCondense
+{
+ public:
+ /// default constructor
+ QtSome();
+
+ /// constructor getting the operand
+ QtSome( QtOperation* input );
+
+ /// optimizes the tree
+// virtual void rewriteOps();
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method returning class name
+ inline virtual const char* getClassName() const;
+
+ /// method returning algebraic identifier
+ inline virtual const char* getAlgebraicName() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the specialized condenser {\tt all_cells()} in the query tree.
+
+*/
+
+class QtAll : public QtCondense
+{
+ public:
+ /// default constructor
+ QtAll();
+
+ /// constructor getting the operand
+ QtAll( QtOperation* input );
+
+ /// optimizes the tree
+// virtual void rewriteOps();
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method returning class name
+ inline virtual const char* getClassName() const;
+
+ /// method returning algebraic identifier
+ inline virtual const char* getAlgebraicName() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the specialized condenser {\tt count_cells()} in the query tree.
+
+*/
+
+class QtCountCells : public QtCondense
+{
+ public:
+ /// default constructor
+ QtCountCells();
+
+ /// constructor getting the operand
+ QtCountCells( QtOperation* input );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method returning class name
+ inline virtual const char* getClassName() const;
+
+ /// method returning algebraic identifier
+ inline virtual const char* getAlgebraicName() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the specialized condenser {\tt add_cells()} in the query tree.
+
+*/
+
+class QtAddCells : public QtCondense
+{
+ public:
+ /// default constructor
+ QtAddCells();
+
+ /// constructor getting the operand
+ QtAddCells( QtOperation* input );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method returning class name
+ inline virtual const char* getClassName() const;
+
+ /// method returning algebraic identifier
+ inline virtual const char* getAlgebraicName() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the specialized condenser {\tt avg_cells()} in the query tree.
+
+*/
+
+class QtAvgCells : public QtCondense
+{
+ public:
+ /// default constructor
+ QtAvgCells();
+
+ /// constructor getting the operand
+ QtAvgCells( QtOperation* input );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method returning class name
+ inline virtual const char* getClassName() const;
+
+ /// method returning algebraic identifier
+ inline virtual const char* getAlgebraicName() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the specialized condenser {\tt min_cells()} in the query tree.
+
+*/
+
+class QtMinCells : public QtCondense
+{
+ public:
+ /// default constructor
+ QtMinCells();
+
+ /// constructor getting the operand
+ QtMinCells( QtOperation* input );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method returning class name
+ inline virtual const char* getClassName() const;
+
+ /// method returning algebraic identifier
+ inline virtual const char* getAlgebraicName() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the specialized condenser {\tt max_cells()} in the query tree.
+
+*/
+
+class QtMaxCells : public QtCondense
+{
+ public:
+ /// default constructor
+ QtMaxCells();
+
+ /// constructor getting the operand
+ QtMaxCells( QtOperation* input );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method returning class name
+ inline virtual const char* getClassName() const;
+
+ /// method returning algebraic identifier
+ inline virtual const char* getAlgebraicName() const;
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+#include "qlparser/qtcondense.icc"
+
+#endif
+
diff --git a/qlparser/qtcondense.icc b/qlparser/qtcondense.icc
new file mode 100644
index 0000000..81d8552
--- /dev/null
+++ b/qlparser/qtcondense.icc
@@ -0,0 +1,197 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const char*
+QtCondense::getClassName() const
+{
+ return "QtCondense";
+}
+
+
+inline const char*
+QtCondense::getAlgebraicName() const
+{
+ return "condense_cells";
+}
+
+
+
+inline const QtNode::QtNodeType
+QtSome::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const char*
+QtSome::getClassName() const
+{
+ return "QtSome";
+}
+
+
+inline const char*
+QtSome::getAlgebraicName() const
+{
+ return "some_cells";
+}
+
+
+
+inline const QtNode::QtNodeType
+QtAll::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const char*
+QtAll::getClassName() const
+{
+ return "QtAll";
+}
+
+
+inline const char*
+QtAll::getAlgebraicName() const
+{
+ return "all_cells";
+}
+
+
+inline const QtNode::QtNodeType
+QtCountCells::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const char*
+QtCountCells::getClassName() const
+{
+ return "QtCountCells";
+}
+
+
+inline const char*
+QtCountCells::getAlgebraicName() const
+{
+ return "count_cells";
+}
+
+
+inline const QtNode::QtNodeType
+QtAddCells::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const char*
+QtAddCells::getClassName() const
+{
+ return "QtAddCells";
+}
+
+
+inline const char*
+QtAddCells::getAlgebraicName() const
+{
+ return "add_cells";
+}
+
+
+inline const QtNode::QtNodeType
+QtAvgCells::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const char*
+QtAvgCells::getClassName() const
+{
+ return "QtAvgCells";
+}
+
+
+inline const char*
+QtAvgCells::getAlgebraicName() const
+{
+ return "avg_cells";
+}
+
+
+
+inline const QtNode::QtNodeType
+QtMinCells::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const char*
+QtMinCells::getClassName() const
+{
+ return "QtMinCells";
+}
+
+
+inline const char*
+QtMinCells::getAlgebraicName() const
+{
+ return "min_cells";
+}
+
+
+
+inline const QtNode::QtNodeType
+QtMaxCells::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const char*
+QtMaxCells::getClassName() const
+{
+ return "QtMaxCells";
+}
+
+
+inline const char*
+QtMaxCells::getAlgebraicName() const
+{
+ return "max_cells";
+}
+
+
+
+
diff --git a/qlparser/qtcondenseop.cc b/qlparser/qtcondenseop.cc
new file mode 100644
index 0000000..a20f956
--- /dev/null
+++ b/qlparser/qtcondenseop.cc
@@ -0,0 +1,440 @@
+/*
+* 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, QtCondenseOp: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtcondenseop.cc,v 1.18 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtcondenseop.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtpointdata.hh"
+#include "qlparser/qtmintervaldata.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtcomplexdata.hh"
+
+#include "mddmgr/mddobj.hh"
+
+#include "catalogmgr/typefactory.hh"
+
+#include "catalogmgr/algebraops.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+
+const QtNode::QtNodeType QtCondenseOp::nodeType = QT_CONDENSEOP;
+
+QtCondenseOp::QtCondenseOp( Ops::OpType newOperation,
+ const string &initIteratorName,
+ QtOperation* mintervalExp,
+ QtOperation* cellExp,
+ QtOperation* condExp )
+ : operation( newOperation ),
+ iteratorName( initIteratorName ),
+ QtBinaryOperation( mintervalExp, cellExp ),
+ condOp( condExp )
+{
+}
+
+
+
+QtCondenseOp::~QtCondenseOp()
+{
+ if( condOp )
+ {
+ delete condOp;
+ condOp=NULL;
+ }
+}
+
+
+
+QtNode::QtNodeList*
+QtCondenseOp::getChilds( QtChildType flag )
+{
+ RMDBCLASS( "QtCondenseOp", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
+ QtNodeList* resultList;
+ resultList = QtBinaryOperation::getChilds( flag );
+ if( condOp )
+ {
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ {
+ QtNodeList* subList=NULL;
+ subList = condOp->getChilds( flag );
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ }
+
+ // add the nodes of the current level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( condOp );
+ }
+
+ return resultList;
+}
+
+
+
+bool
+QtCondenseOp::equalMeaning( QtNode* node )
+{
+ RMDBCLASS( "QtCondenseOp", "equalMeaning( QtNode* )", "qlparser", __FILE__, __LINE__ )
+
+ bool result = false;
+
+ if( nodeType == node->getNodeType() )
+ {
+ QtCondenseOp* condNode;
+ condNode = (QtCondenseOp*) node; // by force
+
+ // check domain and cell expression
+ result = QtBinaryOperation::equalMeaning( condNode );
+
+ // check condition expression
+ result &= ( !condOp && !condNode->getCondOp() ) ||
+ condOp->equalMeaning( condNode->getCondOp() );
+ };
+
+ return ( result );
+}
+
+
+
+string
+QtCondenseOp::getSpelling()
+{
+ char tempStr[20];
+ sprintf(tempStr, "%ud", (unsigned long)getNodeType());
+ string result = string(tempStr);
+ result.append( "(" );
+ result.append( QtBinaryOperation::getSpelling() );
+ result.append( "," );
+
+ if( condOp )
+ result.append( condOp->getSpelling() );
+ else
+ result.append( "<nn>" );
+
+ result.append( ")" );
+
+ return result;
+}
+
+
+void
+QtCondenseOp::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ QtBinaryOperation::setInput( inputOld, inputNew );
+
+ if( condOp == inputOld )
+ {
+ condOp = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+};
+
+
+
+void
+QtCondenseOp::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtCondenseOp", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ // delete the trimList and optimize subtrees
+
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ QtBinaryOperation::optimizeLoad( new QtNode::QtTrimList() );
+
+ if( condOp )
+ condOp->optimizeLoad( new QtNode::QtTrimList() );
+}
+
+
+void
+QtCondenseOp::simplify()
+{
+ RMDBCLASS( "QtCondenseOp", "simplify()", "qlparser", __FILE__, __LINE__ )
+
+ RMDBGMIDDLE(1, RMDebug::module_qlparser, "QtCondenseOp", "simplify() warning: QtCondenseOp itself is not simplified yet")
+
+ // Default method for all classes that have no implementation.
+ // Method is used bottom up.
+
+ QtNodeList* resultList=NULL;
+ QtNodeList::iterator iter;
+
+ resultList = getChilds( QT_DIRECT_CHILDS );
+ for( iter=resultList->begin(); iter!=resultList->end(); iter++ )
+ (*iter)->simplify();
+
+ delete resultList;
+ resultList=NULL;
+}
+
+
+bool
+QtCondenseOp::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+QtData*
+QtCondenseOp::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtCondenseOp", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand1 = NULL;
+
+ if( getOperand( inputList, operand1, 1 ) )
+ {
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand1->getDataType() != QT_MINTERVAL )
+ RMInit::logOut << "Internal error in QtMarrayOp::evaluate() - "
+ << "runtime type checking failed (Minterval)." << endl;
+
+ // delete old operand
+ if( operand1 ) operand1->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ r_Minterval domain = ((QtMintervalData*)operand1)->getMintervalData();
+
+ RMDBGMIDDLE(1, RMDebug::module_qlparser, "QtCondenseOp", "Marray domain " << domain)
+
+ // determine aggregation type
+ BaseType* cellType = (BaseType*) input2->getDataStreamType().getType();
+
+ // get operation object
+ BinaryOp* cellBinOp = Ops::getBinaryOp( operation, cellType, cellType, cellType );
+
+ // create execution object QLCondenseOp
+ QLCondenseOp* qlCondenseOp = new QLCondenseOp( input2, condOp, inputList, iteratorName,
+ cellType, 0, cellBinOp );
+
+ // result buffer
+ char* result=NULL;
+
+ try
+ {
+ // execute query engine marray operation
+ result = Tile::execGenCondenseOp( qlCondenseOp, domain );
+ }
+ catch(...)
+ {
+ // free ressources
+ delete qlCondenseOp;
+ qlCondenseOp=NULL;
+ delete cellBinOp;
+ cellBinOp=NULL;
+ if( operand1 ) operand1->deleteRef();
+
+ throw;
+ }
+
+ // allocate cell buffer
+ char* resultBuffer = new char[ cellType->getSize() ];
+
+ // copy cell content
+ memcpy( (void*)resultBuffer, (void*)result, cellType->getSize() );
+
+ delete qlCondenseOp;
+ qlCondenseOp=NULL;
+ delete cellBinOp;
+ cellBinOp=NULL;
+
+ // create data object for the cell
+ QtScalarData* scalarDataObj = NULL;
+ if( cellType->getType() == STRUCT )
+ scalarDataObj = new QtComplexData();
+ else
+ scalarDataObj = new QtAtomicData();
+
+ scalarDataObj->setValueType ( cellType );
+ scalarDataObj->setValueBuffer( resultBuffer );
+
+ // set return data object
+ returnValue = scalarDataObj;
+
+ // delete old operands
+ if( operand1 ) operand1->deleteRef();
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtCondenseOp::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtCondenseOp Object " << getNodeType() << endl;
+
+ s << SPACE_STR(tab).c_str() << "Iterator Name: " << iteratorName.c_str() << endl;
+
+ QtBinaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtCondenseOp::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ s << iteratorName.c_str() << ",";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ",";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtTypeElement&
+QtCondenseOp::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtCondenseOp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input1 && input2 )
+ {
+
+ // check domain expression
+ const QtTypeElement& domainExp = input1->checkType( typeTuple );
+
+ if( domainExp.getDataType() != QT_MINTERVAL )
+ {
+ RMInit::logOut << "Error: QtMarrayOp::checkType() - Can not evaluate domain expression to an minterval" << endl;
+ parseInfo.setErrorNo(401);
+ throw parseInfo;
+ }
+
+ // add domain iterator to the list of bounded variables
+ bool newList = false;
+ if( !typeTuple )
+ {
+ typeTuple = new QtTypeTuple();
+ newList = true;
+ }
+ typeTuple->tuple.push_back( QtTypeElement( QT_POINT, iteratorName.c_str() ) );
+
+ //
+ // check value expression
+ //
+
+ // get value expression type
+ const QtTypeElement& valueExp = input2->checkType( typeTuple );
+
+ // check type
+ if( valueExp.getDataType() != QT_BOOL && valueExp.getDataType() != QT_COMPLEX &&
+ valueExp.getDataType() != QT_CHAR && valueExp.getDataType() != QT_OCTET &&
+ valueExp.getDataType() != QT_USHORT && valueExp.getDataType() != QT_SHORT &&
+ valueExp.getDataType() != QT_ULONG && valueExp.getDataType() != QT_LONG &&
+ valueExp.getDataType() != QT_FLOAT && valueExp.getDataType() != QT_DOUBLE )
+ {
+ RMInit::logOut << "Error: QtMarrayOp::checkType() - Value expression must be either of type atomic or complex" << endl;
+ parseInfo.setErrorNo(412);
+ throw parseInfo;
+ }
+
+ dataStreamType = valueExp;
+
+ //
+ // check condition expression
+ //
+
+ if( condOp )
+ {
+ // get value expression type
+ const QtTypeElement& condExp = condOp->checkType( typeTuple );
+
+ // check type
+ if( condExp.getDataType() != QT_BOOL )
+ {
+ RMInit::logOut << "Error: QtMarrayOp::checkType() - Condition expression must be of type boolean" << endl;
+ parseInfo.setErrorNo(413);
+ throw parseInfo;
+ }
+ }
+
+ // remove iterator again
+ typeTuple->tuple.pop_back();
+ if( newList )
+ {
+ delete typeTuple;
+ typeTuple = NULL;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtCondenseOp::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
diff --git a/qlparser/qtcondenseop.hh b/qlparser/qtcondenseop.hh
new file mode 100644
index 0000000..d1c3e8e
--- /dev/null
+++ b/qlparser/qtcondenseop.hh
@@ -0,0 +1,131 @@
+#ifndef _QTCONDENSEOP_
+#define _QTCONDENSEOP_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtbinaryoperation.hh"
+
+#include "catalogmgr/ops.hh"
+#include <stdio.h>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the root of a cond expression.
+
+*/
+
+class QtCondenseOp : public QtBinaryOperation
+{
+ public:
+ /// constructor getting iterator, minterval exp, cell exp, and cell condition exp (optional)
+ QtCondenseOp( Ops::OpType newOperation,
+ const std::string& initIteratorName,
+ QtOperation* mintervalExp,
+ QtOperation* cellExp,
+ QtOperation* condExp = NULL );
+
+ /// virtual destructor
+ ~QtCondenseOp();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// test if the two nodes have an equal meaning in a subtree
+ virtual bool equalMeaning( QtNode* node );
+
+ /// creates a unique name for a common subexpression
+ virtual std::string getSpelling();
+
+ /// method for query rewrite
+ virtual void setInput( QtOperation* inputOld, QtOperation* inputNew );
+
+ /// optimizing load access
+ void optimizeLoad( QtTrimList* trimList );
+
+ /// simplifies the tree
+ virtual void simplify();
+
+ /// returns FALSE saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+
+ ///
+ inline QtOperation* getCondOp();
+
+ ///
+ //@}
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+
+ /// attribute storing the iterator name
+ std::string iteratorName;
+
+ /// attribute storing optional cell condition expression
+ QtOperation* condOp;
+
+ /// attribute storing condensing operation
+ Ops::OpType operation;
+};
+
+
+#include "qlparser/qtcondenseop.icc"
+
+#endif
+
diff --git a/qlparser/qtcondenseop.icc b/qlparser/qtcondenseop.icc
new file mode 100644
index 0000000..6ba6fad
--- /dev/null
+++ b/qlparser/qtcondenseop.icc
@@ -0,0 +1,44 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtCondenseOp::getNodeType() const
+{
+ return nodeType;
+}
+
+
+
+inline QtOperation*
+QtCondenseOp::getCondOp()
+{
+ return condOp;
+}
+
+
diff --git a/qlparser/qtconst.cc b/qlparser/qtconst.cc
new file mode 100644
index 0000000..b4896f0
--- /dev/null
+++ b/qlparser/qtconst.cc
@@ -0,0 +1,265 @@
+/*
+* 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, QtConst: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtconst.cc,v 1.22 2005/07/06 22:48:34 rasdev Exp $";
+
+#include "qlparser/qtconst.hh"
+#include "qlparser/qtscalardata.hh"
+#include "qlparser/qtstringdata.hh"
+
+#include "qlparser/qtmdd.hh" // these three can be deleted with new memory management
+
+#include "relcatalogif/basetype.hh"
+#include "mddmgr/mddobj.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+#include <iostream>
+
+// deprecated, not available any longer -- PB 2005-jan-14
+// #include <strstream.h>
+
+const QtNode::QtNodeType QtConst::nodeType = QtNode::QT_CONST;
+
+
+QtConst::QtConst( QtData* newDataObj )
+ : QtOperation(),
+ dataObj( newDataObj )
+{
+ // store parse info of the data object
+ setParseInfo( dataObj->getParseInfo() );
+}
+
+
+
+QtConst::~QtConst()
+{
+ if( dataObj ) dataObj->deleteRef();
+}
+
+
+
+bool
+QtConst::equalMeaning( QtNode* node )
+{
+ RMDBCLASS( "QtConst", "equalMeaning( QtNode* )", "qlparser", __FILE__, __LINE__ )
+
+ bool result = false;
+
+ if( nodeType == node->getNodeType() )
+ {
+ QtConst* constObj = (QtConst*) node;
+
+ result = dataObj->equal( constObj->getDataObj() );
+ }
+
+ return result;
+}
+
+
+string
+QtConst::getSpelling()
+{
+ char tempStr[20];
+ sprintf(tempStr, "%ud", (unsigned long)getNodeType());
+ string result = string(tempStr);
+ result.append( dataObj->getSpelling() );
+
+ return result;
+}
+
+
+QtNode::QtAreaType
+QtConst::getAreaType()
+{
+ if( dataObj && dataObj->getDataType() == QT_MDD )
+ return QT_AREA_MDD;
+ else
+ return QT_AREA_SCALAR;
+}
+
+
+void
+QtConst::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtConst", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ if( trimList )
+ {
+ if( trimList->size() )
+ {
+ if( dataObj && dataObj->getDataType() == QT_MDD )
+ {
+ // get the highest specified dimension
+ r_Dimension maxDimension=0;
+ QtTrimList::iterator i;
+
+ for( i=trimList->begin(); i!=trimList->end(); i++ )
+ // get the maximum
+ maxDimension = maxDimension > (*i)->dimension ? maxDimension : (*i)->dimension;
+
+ // create a new loadDomain object and initialize it with open bounds
+ r_Minterval loadDomain(maxDimension+1);
+
+ // fill the loadDomain object with the QtTrimList specifications
+ for( i=trimList->begin(); i!=trimList->end(); i++ )
+ loadDomain[(*i)->dimension] = (*i)->interval;
+
+ ((QtMDD*)dataObj)->setLoadDomain( loadDomain );
+ }
+
+ // release( trimList->begin(), trimList->end() );
+ vector<QtNode::QtTrimElement*>::iterator iter;
+ for( iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ }
+
+ delete trimList;
+ trimList=NULL;
+ }
+}
+
+
+QtData*
+QtConst::evaluate( QtDataList* /*inputList*/ )
+{
+ RMDBCLASS( "QtConst", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+
+ if( dataObj )
+ {
+ dataObj->incRef();
+ returnValue = dataObj;
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtConst::printTree( int tab, ostream& s, QtChildType /*mode*/ )
+{
+ s << SPACE_STR(tab).c_str() << "QtConst Object: type " << flush;
+ dataStreamType.printStatus( s );
+ s << endl;
+
+ s << SPACE_STR(tab).c_str() << " ";
+
+ if( dataObj )
+ dataObj->printStatus( s );
+ else
+ s << "<no data object>";
+
+ s << endl;
+}
+
+
+
+void
+QtConst::printAlgebraicExpression( ostream& s )
+{
+ if( dataObj->isScalarData() )
+ {
+ QtScalarData* scalarDataObj = (QtScalarData*)dataObj;
+
+ if( scalarDataObj->getValueType() )
+ {
+ // Print the value but first cut leading blanks.
+ char valueString[1024];
+ // replaced deprecated ostrstream -- PB 2005-jan-14
+ // ostrstream valueStream( valueString, 1024 );
+ ostringstream valueStream( valueString );
+
+ scalarDataObj->getValueType()->printCell( valueStream, scalarDataObj->getValueBuffer() );
+
+ valueStream << ends;
+
+ char* p = valueString;
+ while( *p == ' ' ) p++;
+
+ s << p;
+ }
+ else
+ s << "<nn>";
+ }
+ else if( dataObj->getDataType() == QT_STRING )
+ {
+ s << ((QtStringData*)dataObj)->getStringData().c_str();
+ }
+ else
+ s << "<nn>";
+}
+
+
+
+const QtTypeElement&
+QtConst::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtConst", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ if( dataObj )
+ {
+ switch( dataObj->getDataType() )
+ {
+ case QT_STRING:
+ case QT_INTERVAL:
+ case QT_MINTERVAL:
+ case QT_POINT:
+ dataStreamType.setDataType( dataObj->getDataType() );
+ break;
+ case QT_MDD:
+ if( ((QtMDD*)dataObj)->getMDDObject() )
+ dataStreamType.setType((Type*)((QtMDD*)dataObj)->getMDDObject()->getMDDBaseType() );
+ break;
+ default:
+ dataStreamType.setType( ((QtScalarData*)dataObj)->getValueType() );
+ }
+ }
+
+ return dataStreamType;
+}
+
+
+
diff --git a/qlparser/qtconst.hh b/qlparser/qtconst.hh
new file mode 100644
index 0000000..6dce957
--- /dev/null
+++ b/qlparser/qtconst.hh
@@ -0,0 +1,117 @@
+#ifndef _QTCONST_
+#define _QTCONST_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtoperation.hh"
+#include <stdio.h>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class serves as a carrier for a {\tt QtData} object
+ and, additionally, provides functionality necessary in
+ the query tree.
+
+*/
+
+class QtConst : public QtOperation
+{
+ public:
+ /// constructor getting a pointer to the data object
+ QtConst( QtData* newDataObj );
+ /**
+ Lifetime of {\tt newDataObj} is managed by this class from now on.
+ */
+
+ /// virtual destructor
+ virtual ~QtConst();
+
+ /// test if the two nodes have an equal meaning in the query tree
+ virtual bool equalMeaning( QtNode* node );
+
+ /// creates a unique name for a common subexpression
+ virtual std::string getSpelling();
+
+ /// test if the edge to the parent node is of type mdd or atomic
+ virtual QtAreaType getAreaType();
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ //@Man: Operations of the ONC protocol:
+ //@{
+ ///
+ QtDataList* next();
+ //@}
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ /// return the data object
+ inline QtData* getDataObj();
+ ///
+ //@}
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// pointer to the data object
+ QtData* dataObj;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtconst.icc"
+
+#endif
+
diff --git a/qlparser/qtconst.icc b/qlparser/qtconst.icc
new file mode 100644
index 0000000..9d968d6
--- /dev/null
+++ b/qlparser/qtconst.icc
@@ -0,0 +1,43 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtConst::getNodeType() const
+{
+ return nodeType;
+}
+
+
+
+inline QtData*
+QtConst::getDataObj()
+{
+ return dataObj;
+}
+
diff --git a/qlparser/qtconversion.cc b/qlparser/qtconversion.cc
new file mode 100644
index 0000000..72d751f
--- /dev/null
+++ b/qlparser/qtconversion.cc
@@ -0,0 +1,590 @@
+/*
+* 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, QtConversion: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtconversion.cc,v 1.36 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "raslib/rmdebug.hh"
+#include "raslib/basetype.hh"
+#include "raslib/structuretype.hh"
+#include "conversion/convertor.hh"
+#include "conversion/convfactory.hh"
+
+#include "qlparser/qtconversion.hh"
+#include "qlparser/qtmdd.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "tilemgr/tile.hh"
+
+#include "catalogmgr/typefactory.hh"
+#include "relcatalogif/typeiterator.hh"
+#include "relcatalogif/structtype.hh"
+#include "relcatalogif/chartype.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+const QtNode::QtNodeType QtConversion::nodeType = QtNode::QT_CONVERSION;
+
+
+QtConversion::QtConversion( QtOperation* newInput, QtConversionType
+newConversionType, const char* s )
+ : conversionType( newConversionType ), QtUnaryOperation( newInput ), paramStr(s)
+{
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "QtConversion()" )
+}
+
+void
+QtConversion::setConversionTypeByName( string formatName )
+{
+ if(string("bmp") == formatName)
+ conversionType = QtConversion::QT_TOBMP;
+ else if(string("hdf") == formatName )
+ conversionType = QtConversion::QT_TOHDF;
+ else if(string("png") == formatName)
+ conversionType = QtConversion::QT_TOPNG;
+ else if (string("jpeg") == formatName)
+ conversionType = QtConversion::QT_TOJPEG;
+ else if (string("tiff") == formatName)
+ conversionType = QtConversion::QT_TOTIFF;
+ else if (string("vff") == formatName)
+ conversionType = QtConversion::QT_TOVFF;
+ else if (string("csv") == formatName)
+ conversionType = QtConversion::QT_TOCSV;
+ else if (string("tor") == formatName)
+ conversionType = QtConversion::QT_TOTOR;
+ else if (string("dem") == formatName)
+ conversionType = QtConversion::QT_TODEM;
+ else if(string("inv_bmp") == formatName )
+ conversionType = QtConversion::QT_FROMBMP;
+ else if(string("inv_hdf") == formatName )
+ conversionType = QtConversion::QT_FROMHDF;
+ else if(string("inv_csv") == formatName )
+ conversionType = QtConversion::QT_FROMCSV;
+ else if(string("inv_png") == formatName)
+ conversionType = QtConversion::QT_FROMPNG;
+ else if (string("inv_jpeg") == formatName)
+ conversionType = QtConversion::QT_FROMJPEG;
+ else if (string("inv_tiff") == formatName)
+ conversionType = QtConversion::QT_FROMTIFF;
+ else if (string("inv_vff") == formatName)
+ conversionType = QtConversion::QT_FROMVFF;
+ else if (string("inv_tor") == formatName)
+ conversionType = QtConversion::QT_FROMTOR;
+ else if (string("inv_dem") == formatName)
+ conversionType = QtConversion::QT_FROMDEM;
+ else
+ conversionType = QtConversion::QT_UNKNOWN;
+}
+
+bool
+QtConversion::lookupConversionTypeByName( string formatName )
+{
+ return (( string("bmp") == formatName ) || ( string("hdf") == formatName ) ||
+ ( string("png") == formatName ) || ( string("jpeg") == formatName ) ||
+ ( string("dem") == formatName ) || ( string("tor") == formatName ) ||
+ ( string("csv") == formatName ) || ( string("inv_csv") == formatName ) ||
+ ( string("tiff") == formatName ) || ( string("vff") == formatName ) ||
+ ( string("inv_bmp") == formatName ) || ( string("inv_hdf") == formatName ) ||
+ ( string("inv_png") == formatName ) || ( string("inv_jpeg") == formatName ) ||
+ ( string("inv_dem") == formatName ) || ( string("inv_tor") == formatName ) ||
+ ( string("inv_tiff") == formatName ) || ( string("inv_vff") == formatName ));
+
+}
+
+bool
+QtConversion::equalMeaning( QtNode* node )
+{
+
+ bool result = false;
+
+ if( nodeType == node->getNodeType() )
+ {
+ QtConversion* convNode;
+ convNode = (QtConversion*) node; // by force
+
+ result = input->equalMeaning( convNode->getInput() );
+
+ result &= conversionType == convNode->conversionType;
+ };
+
+ return ( result );
+}
+
+
+QtData*
+QtConversion::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtConversion", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if( conversionType == QT_UNKNOWN )
+ {
+ RMInit::logOut << "Error: QtConversion::evaluate() - unknown conversion format." << std::endl;
+ parseInfo.setErrorNo(382);
+ throw parseInfo;
+ }
+
+ operand = input->evaluate( inputList );
+
+ if( operand )
+ {
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Internal error in QtConversion::evaluate() - "
+ << "runtime type checking failed (MDD)." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ return 0;
+ }
+#endif
+
+ QtMDD* qtMDD = (QtMDD*) operand;
+ MDDObj* currentMDDObj = qtMDD->getMDDObject();
+ Tile* sourceTile = NULL;
+ vector< Tile* >* tiles = NULL;
+ if (qtMDD->getLoadDomain().is_origin_fixed() && qtMDD->getLoadDomain().is_high_fixed())
+ {
+ // get relevant tiles
+ tiles = currentMDDObj->intersect( qtMDD->getLoadDomain() );
+ }
+ else {
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - no tile available to convert." )
+ return operand;
+ }
+
+ // check the number of tiles
+ if( !tiles->size() )
+ {
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - no tile available to convert." )
+ return operand;
+ }
+
+ // create one single tile with the load domain
+ sourceTile = new Tile( tiles, qtMDD->getLoadDomain() );
+
+ // delete the tile vector
+ delete tiles;
+ tiles = NULL;
+
+ // get type structure of the operand base type
+ char* typeStructure = qtMDD->getCellType()->getTypeStructure();
+
+ // convert structure to r_Type
+ r_Type* baseSchema = r_Type::get_any_type( typeStructure );
+
+ free( typeStructure );
+ typeStructure = NULL;
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - no tile available to convert." )
+ RMDBGIF(2, RMDebug::module_qlparser, "QtConversion", \
+ RMInit::dbgOut << "Cell base type for conversion: " << std::flush; \
+ baseSchema->print_status( RMInit::dbgOut ); \
+ RMInit::dbgOut << std::endl; )
+
+ //
+ // real conversion
+ //
+
+ r_convDesc convResult;
+ r_Minterval tileDomain = sourceTile->getDomain();
+
+ //convertor type
+ r_Data_Format convType = r_Array;
+ //result type from convertor
+ r_Data_Format convFormat = r_Array;
+
+ switch (conversionType)
+ {
+ case QT_TOTIFF:
+ convType = r_TIFF;
+ convFormat = r_TIFF;
+ break;
+ case QT_FROMTIFF:
+ convType = r_TIFF;
+ convFormat = r_Array;
+ break;
+ case QT_TOBMP:
+ convType = r_BMP;
+ convFormat = r_BMP;
+ break;
+ case QT_FROMBMP:
+ convType = r_BMP;
+ convFormat = r_Array;
+ break;
+ case QT_TOHDF:
+ convType = r_HDF;
+ convFormat = r_HDF;
+ break;
+ case QT_TOCSV:
+ convType = r_CSV;
+ convFormat = r_CSV;
+ break;
+ case QT_FROMHDF:
+ convType = r_HDF;
+ convFormat = r_Array;
+ break;
+ case QT_FROMCSV:
+ convType = r_CSV;
+ convFormat = r_Array;
+ break;
+ case QT_TOJPEG:
+ convType = r_JPEG;
+ convFormat = r_JPEG;
+ break;
+ case QT_FROMJPEG:
+ convType = r_JPEG;
+ convFormat = r_Array;
+ break;
+ case QT_TOPNG:
+ convType = r_PNG;
+ convFormat = r_PNG;
+ break;
+ case QT_FROMPNG:
+ convType = r_PNG;
+ convFormat = r_Array;
+ break;
+ case QT_TOVFF:
+ convType = r_VFF;
+ convFormat = r_VFF;
+ break;
+ case QT_FROMVFF:
+ convType = r_VFF;
+ convFormat = r_Array;
+ break;
+ case QT_TOTOR:
+ convType = r_TOR;
+ convFormat = r_TOR;
+ break;
+ case QT_FROMTOR:
+ convType = r_TOR;
+ convFormat = r_Array;
+ break;
+ case QT_TODEM:
+ convType = r_DEM;
+ convFormat = r_DEM;
+ break;
+ case QT_FROMDEM:
+ convType = r_DEM;
+ convFormat = r_Array;
+ break;
+ default:
+ RMInit::logOut << "Error: QtConversion::evaluate(): unsupported format " << conversionType << std::endl;
+ throw r_Error(CONVERSIONFORMATNOTSUPPORTED);
+ break;
+ }
+ convFormat = r_Array;
+
+ r_Convertor *convertor = NULL;
+
+ try {
+ convertor = r_Convertor_Factory::create(convType, sourceTile->getContents(), tileDomain, baseSchema);
+ if(conversionType < QT_FROMTIFF) {
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - convertor " << convType << " converting to " << convFormat << "...");
+ convResult = convertor->convertTo(paramStr);
+ }
+ else {
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - convertor " << convType << " converting from " << convFormat << "...");
+ convResult = convertor->convertFrom(paramStr);
+ }
+ }
+ catch (r_Error &err) {
+ RMInit::logOut << "Error: QtConversion::evaluate(): conversion failed" << std::endl;
+ delete sourceTile;
+ sourceTile = NULL;
+ delete baseSchema;
+ baseSchema = NULL;
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ if (convertor != NULL) {
+ delete convertor;
+ convertor=NULL;
+ }
+
+ parseInfo.setErrorNo(381);
+ throw parseInfo;
+ }
+ if (convertor != NULL) {
+ delete convertor;
+ convertor=NULL;
+ }
+
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - ok")
+
+
+ //
+ // done
+ //
+
+ // delete sourceTile
+ delete sourceTile;
+ sourceTile = NULL;
+
+ // create a transient tile for the compressed data
+ const BaseType* myType = NULL;
+ const r_Type* currStruct = NULL;
+ if(convResult.destType->isPrimitiveType()) {
+ myType=TypeFactory::mapType(convResult.destType->name());
+ if(myType == NULL) {
+ RMInit::logOut << "Error: QtConversion::evaluate() no primitive type compatible found" << std::endl;
+ delete convResult.destType;
+ convResult.destType=NULL;
+ delete convResult.dest;
+ convResult.dest=NULL;
+ throw r_Error(BASETYPENOTSUPPORTED);
+ }
+
+ if(strcasecmp( dataStreamType.getType()->getTypeName(), myType->getTypeName())) {
+ //FIXME here we have to change the dataStreamType.getType(), is not char for
+ //conversion from_DEF all the time, we don't know the result type until we parse the data
+ MDDBaseType* mddBaseType = new MDDBaseType( "tmp", TypeFactory::mapType(myType->getTypeName()) );
+ TypeFactory::addTempType( mddBaseType );
+
+ dataStreamType.setType( mddBaseType );
+ RMInit::logOut << " QtConversion::evaluate() for conversion " << conversionType << " real result is " << std::flush;
+ dataStreamType.printStatus(RMInit::logOut);
+ RMInit::logOut << std::endl;
+ }
+ }
+ else { //we assume that we deal with structure types
+ TypeIterator<StructType> structIter = TypeFactory::createStructIter();
+ while(structIter.not_done()) {
+ // get type structure of current structtype
+ typeStructure = structIter.get_element()->getTypeStructure();
+ // convert structure to r_Type
+ currStruct = r_Type::get_any_type( typeStructure );
+
+ if(currStruct == NULL) {
+ RMInit::logOut << "Error: QtConversion::evaluate() no structure type compatible found" << std::endl;
+ delete convResult.destType;
+ convResult.destType=NULL;
+ delete convResult.dest;
+ convResult.dest=NULL;
+ throw r_Error(STRUCTTYPE_ELEMENT_UNKNOWN);
+ }
+
+ free(typeStructure);
+ typeStructure = NULL;
+
+ if(((r_Structure_Type*)currStruct)->compatibleWith((r_Structure_Type*)convResult.destType)) {
+ //we found a type
+ delete currStruct;
+ currStruct = NULL;
+ myType=structIter.get_element().ptr();
+ break;
+ }
+
+ delete currStruct;
+ currStruct = NULL;
+ structIter.advance();
+ }
+ if(myType == NULL) {
+ RMInit::logOut << "Error: QtConversion::evaluate() no structure type compatible found" << std::endl;
+ delete convResult.destType;
+ convResult.destType=NULL;
+ delete convResult.dest;
+ convResult.dest=NULL;
+ throw r_Error(STRUCTTYPE_ELEMENT_UNKNOWN);
+ }
+
+ if(strcasecmp(dataStreamType.getType()->getTypeName(), myType->getTypeName())) {
+ //FIXME here we have to change the dataStreamType.getType(), is not char for
+ //conversion from_DEF all the time, we don't know the result type until we parse the data
+ MDDBaseType* mddBaseType = new MDDBaseType( "tmp", TypeFactory::mapType(myType->getTypeName()) );
+ TypeFactory::addTempType( mddBaseType );
+
+ dataStreamType.setType( mddBaseType );
+ RMInit::logOut << " QtConversion::evaluate() for conversion " << conversionType << " real result is " << std::flush;
+ dataStreamType.printStatus(RMInit::logOut);
+ RMInit::logOut << std::endl;
+ }
+ }
+
+ Tile* resultTile = new Tile( convResult.destInterv,
+ myType,
+ convResult.dest,
+ 0,
+ convFormat );
+
+ // delete destination type
+ if( convResult.destType ) {
+ delete convResult.destType;
+ convResult.destType=NULL;
+ }
+
+ // create a transient MDD object for the query result
+ MDDBaseType* mddBaseType = (MDDBaseType*)dataStreamType.getType();
+ MDDObj* resultMDD = new MDDObj( mddBaseType, convResult.destInterv );
+ resultMDD->insertTile( resultTile );
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)resultMDD );
+
+ // delete base type schema
+ delete baseSchema;
+ baseSchema = NULL;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+ else
+ RMInit::logOut << "Error: QtConversion::evaluate() - operand is not provided." << std::endl;
+
+ return returnValue;
+}
+
+
+void
+QtConversion::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtConversion Object: ";
+
+ switch( conversionType )
+ {
+ case QT_TOTIFF: s << "to TIFF"; break;
+ case QT_TOBMP: s << "to BMP"; break;
+ case QT_TOHDF: s << "to HDF"; break;
+ case QT_TOCSV: s << "to CSV"; break;
+ case QT_TOJPEG: s << "to JPEG"; break;
+ case QT_TOPNG: s << "to PNG"; break;
+ case QT_TOVFF: s << "to VFF"; break;
+ case QT_TOTOR: s << "to TOR"; break;
+ case QT_TODEM: s << "to DEM"; break;
+ case QT_FROMTIFF: s << "from TIFF"; break;
+ case QT_FROMBMP: s << "from BMP"; break;
+ case QT_FROMHDF: s << "from HDF"; break;
+ case QT_FROMCSV: s << "from CSV"; break;
+ case QT_FROMJPEG: s << "from JPEG"; break;
+ case QT_FROMPNG: s << "from PNG"; break;
+ case QT_FROMVFF: s << "from VFF"; break;
+ case QT_FROMTOR: s << "from TOR"; break;
+ case QT_FROMDEM: s << "from DEM"; break;
+ default: s << "unknown conversion"; break;
+ }
+
+ s << std::endl;
+
+ QtUnaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtConversion::printAlgebraicExpression( ostream& s )
+{
+ s << conversionType << "(";
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtTypeElement&
+QtConversion::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtConversion", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input type
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ if( inputType.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtConversion::checkType() - operand is not of type MDD." << std::endl;
+ parseInfo.setErrorNo(380);
+ throw parseInfo;
+ }
+
+ //FIXME we set for every kind of conversion the result type char
+ //for conversion from_DEF we don't know the result type until we parse the data
+ MDDBaseType* mddBaseType = new MDDBaseType( "Char", TypeFactory::mapType("Char") );
+ TypeFactory::addTempType( mddBaseType );
+
+ dataStreamType.setType( mddBaseType );
+
+ if(conversionType>QT_TODEM) {
+ RMInit::logOut << std::endl << "QtConversion::checkType() for conversion " << conversionType << " assume the result " << std::flush;
+ dataStreamType.printStatus(RMInit::logOut);
+ RMInit::logOut << std::endl;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtConversion::checkType() - operand branch invalid." << std::endl;
+
+ return dataStreamType;
+}
+
+std::ostream&
+operator<< (std::ostream& os, QtConversion::QtConversionType type) {
+ switch( type )
+ {
+ case QtConversion::QT_TOTIFF: os << "tiff"; break;
+ case QtConversion::QT_TOBMP: os << "bmp"; break;
+ case QtConversion::QT_TOHDF: os << "hdf"; break;
+ case QtConversion::QT_TOCSV: os << "csv"; break;
+ case QtConversion::QT_TOJPEG: os << "jpeg"; break;
+ case QtConversion::QT_TOPNG: os << "png"; break;
+ case QtConversion::QT_TOVFF: os << "vff"; break;
+ case QtConversion::QT_TOTOR: os << "tor"; break;
+ case QtConversion::QT_TODEM: os << "dem"; break;
+ case QtConversion::QT_FROMTIFF: os << "inv_tiff"; break;
+ case QtConversion::QT_FROMBMP: os << "inv_bmp"; break;
+ case QtConversion::QT_FROMHDF: os << "inv_hdf"; break;
+ case QtConversion::QT_FROMCSV: os << "inv_csv"; break;
+ case QtConversion::QT_FROMJPEG: os << "inv_jpeg"; break;
+ case QtConversion::QT_FROMPNG: os << "inv_png"; break;
+ case QtConversion::QT_FROMVFF: os << "inv_vff"; break;
+ case QtConversion::QT_FROMTOR: os << "inv_tor"; break;
+ case QtConversion::QT_FROMDEM: os << "inv_dem"; break;
+ default: os << "unknown Conversion"; break;
+ }
+
+ return os;
+}
+
diff --git a/qlparser/qtconversion.hh b/qlparser/qtconversion.hh
new file mode 100644
index 0000000..6bb44bc
--- /dev/null
+++ b/qlparser/qtconversion.hh
@@ -0,0 +1,113 @@
+#ifndef _QTCONVERSION_HH__
+#define _QTCONVERSION_HH___
+
+#include "qlparser/qtunaryoperation.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents a format conversion. The conversion is described by
+ an enumerator.
+
+*/
+
+class QtConversion : public QtUnaryOperation
+{
+ public:
+ enum QtConversionType
+ {
+ QT_UNKNOWN,
+ QT_TOTIFF,
+ QT_TOBMP,
+ QT_TOHDF,
+ QT_TOCSV,
+ QT_TOJPEG,
+ QT_TOPNG,
+ QT_TOVFF,
+ QT_TOTOR,
+ QT_TODEM,
+ QT_FROMTIFF,
+ QT_FROMBMP,
+ QT_FROMHDF,
+ QT_FROMCSV,
+ QT_FROMJPEG,
+ QT_FROMPNG,
+ QT_FROMVFF,
+ QT_FROMTOR,
+ QT_FROMDEM
+ };
+
+ /// constructor getting operand and format conversion type
+ QtConversion( QtOperation* newInput, QtConversionType newConversionType, const char* = NULL );
+
+ /// set the format conversion type by name
+ void setConversionTypeByName( std::string formatName );
+
+ /// look up the format conversion type by name
+ static bool lookupConversionTypeByName( std::string formatName );
+
+ /// test if the two nodes have an equal meaning in a subtree
+ virtual bool equalMeaning( QtNode* node );
+
+ /// evaluates the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute storing conversion type
+ QtConversionType conversionType;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+
+ const char* paramStr;
+};
+
+extern std::ostream& operator<<(std::ostream& os, QtConversion::QtConversionType t);
+
+#include "qlparser/qtconversion.icc"
+
+#endif
+
diff --git a/qlparser/qtconversion.icc b/qlparser/qtconversion.icc
new file mode 100644
index 0000000..410e34e
--- /dev/null
+++ b/qlparser/qtconversion.icc
@@ -0,0 +1,35 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const QtNode::QtNodeType
+QtConversion::getNodeType() const
+{
+ return nodeType;
+}
diff --git a/qlparser/qtdata.cc b/qlparser/qtdata.cc
new file mode 100644
index 0000000..1ef0735
--- /dev/null
+++ b/qlparser/qtdata.cc
@@ -0,0 +1,127 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, QtData: $Id: qtdata.cc,v 1.17 2002/06/05 18:18:17 coman Exp $";
+
+#include "raslib/rmdebug.hh"
+#include "qlparser/qtdata.hh"
+
+
+QtData::QtData()
+ : referenceCounter(1),
+ persistent( QT_TRANSIENT ),
+ parseInfo(NULL)
+{
+ RMDBGONCE( 10, RMDebug::module_qlparser, "QtData", "QtData::QtData() Obj: " << this )
+}
+
+
+
+QtData::QtData( const std::string name )
+ : iteratorName( name ),
+ referenceCounter(1),
+ persistent( QT_TRANSIENT ),
+ parseInfo(NULL)
+{
+ RMDBGONCE( 10, RMDebug::module_qlparser, "QtData", "QtData::QtData( const std::string ) Obj: " << this )
+}
+
+
+
+QtData::QtData( const QtData &obj )
+ : iteratorName( obj.iteratorName ),
+ persistent( obj.persistent ),
+ referenceCounter(1),
+ parseInfo(NULL)
+{
+ RMDBGONCE( 10, RMDebug::module_qlparser, "QtData", "QtData::QtData( QtData& ) Obj: " << this )
+
+ if( obj.parseInfo )
+ parseInfo = new ParseInfo( *(obj.parseInfo) );
+}
+
+
+
+QtData::~QtData()
+{
+ RMDBGONCE( 10, RMDebug::module_qlparser, "QtData", "QtData::~QtData() Obj: " << this )
+
+ if( parseInfo )
+ {
+ delete parseInfo;
+ parseInfo=NULL;
+ }
+}
+
+
+
+bool
+QtData::isScalarData() const
+{
+ // default implementation returns false
+ return false;
+}
+
+
+
+const QtData&
+QtData::operator=( const QtData& obj )
+{
+ RMDBGONCE( 10, RMDebug::module_qlparser, "QtData", "QtData::operator=" )
+
+ if( this != &obj )
+ {
+ iteratorName = obj.iteratorName;
+ persistent = obj.persistent;
+ referenceCounter = 1;
+
+ if( parseInfo )
+ {
+ delete parseInfo;
+ parseInfo = NULL;
+ }
+
+ if( obj.parseInfo )
+ parseInfo = new ParseInfo( *(obj.parseInfo) );
+ }
+
+ return *this;
+}
+
+
+
+void
+QtData::printStatus( std::ostream& stream ) const
+{
+ if( iteratorName.size() )
+ stream << ", iter name: " << iteratorName.c_str() << std::flush;
+
+ stream << ", ref#: " << referenceCounter
+ << ( persistent == QT_TRANSIENT ? " trans " : " pers " ) << std::flush;
+}
diff --git a/qlparser/qtdata.hh b/qlparser/qtdata.hh
new file mode 100644
index 0000000..ee2e285
--- /dev/null
+++ b/qlparser/qtdata.hh
@@ -0,0 +1,200 @@
+#ifndef _QTDATA_
+#define _QTDATA_
+
+#include <iostream>
+
+#include "qlparser/parseinfo.hh"
+#include "raslib/rminit.hh"
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@Man: TypeEnum
+//@Type: typedef
+//@Memo: Module: {\bf qlparser}.
+
+enum QtDataType
+{
+ QT_TYPE_UNKNOWN,
+ QT_BOOL,
+ QT_CHAR,
+ QT_OCTET,
+ QT_USHORT,
+ QT_SHORT,
+ QT_ULONG,
+ QT_LONG,
+ QT_FLOAT,
+ QT_DOUBLE,
+ QT_COMPLEXTYPE1, // with float members
+ QT_COMPLEXTYPE2, // with double
+ QT_MDD,
+ QT_COMPLEX,
+ QT_STRING,
+ QT_INTERVAL,
+ QT_MINTERVAL,
+ QT_POINT
+};
+
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+This class is superclass for the classes representing a
+specific data type handled by the query tree.
+
+*/
+
+class QtData
+{
+ public:
+ // construktor
+ QtData();
+
+ // constructor
+ QtData( const std::string name );
+
+ /// copy constructor
+ QtData( const QtData &obj );
+
+ /// destructor
+ virtual ~QtData();
+
+ /// assignement operator
+ const QtData& operator=( const QtData& obj );
+
+ enum QtLifetime
+ {
+ QT_PERSISTENT,
+ QT_TRANSIENT
+ };
+
+ /// returns type of data represented by the QtData object
+ virtual QtDataType getDataType() const = 0;
+ /**
+ \begin{tabular}{lll}
+ QtMDD&&QT_MDD\\
+ QtAtomicData&&QT_BOOL\\
+ &&QT_CHAR\\
+ &&QT_OCTET\\
+ &&QT_USHORT\\
+ &&QT_SHORT\\
+ &&QT_ULONG\\
+ &&QT_FLOAT\\
+ &&QT_DOUBLE\\
+ QtComplexData&&QT_COMPLEX\\
+ QtString&&QT_STRING\\
+ QtInterval&&QT_INTERVAL\\
+ QtMinterval&&QT_MINTERVAL\\
+ QtPoint&&QT_POINT\\
+ \end{tabular}
+ */
+
+ /// returns a null-terminated string describing the type structure
+ virtual char* getTypeStructure() const = 0;
+ /**
+ The string pointer has to be free using free() by the caller.
+ */
+
+ /// determines, if the data is of type scalar
+ virtual bool isScalarData() const;
+
+ /// compares data content
+ virtual bool equal( const QtData* obj ) const = 0;
+
+ /// returns content dependent string representation
+ virtual std::string getSpelling() const = 0;
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+
+ /// get the iterator name
+ inline std::string const getIteratorName() const;
+ ///
+ inline void setIteratorName( const std::string & iteratorNameNew );
+ ///
+ inline QtLifetime const getLifetime() const;
+ ///
+ inline void setLifetime( QtLifetime flag );
+ /// return number of references to the self object
+ inline unsigned int getRefNo() const;
+ /// increases the reference counter by one
+ inline void incRef();
+ /// deletes one reference and the object if it was the last one
+ inline int deleteRef();
+ /**
+ In case the object is deleted, 1 is returned, 0 otherwise.
+ */
+
+ ///
+ inline ParseInfo getParseInfo();
+ ///
+ inline void setParseInfo( const ParseInfo &info );
+
+ ///
+ //@}
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+
+ protected:
+ /// pointer to an optional parser info
+ ParseInfo* parseInfo;
+
+ private:
+ /// decreases the reference counter by one and returns the new value
+ inline unsigned int decRef();
+
+ /// attribute storing the iterator name
+ std::string iteratorName;
+
+ /// attribute storing the lifetime (persistent, transient)
+ QtLifetime persistent;
+ /**
+ Objects of subclasses of QtScalarData (QtAtomicData and QtComplexdata) are always transient.
+ Objects of subclass QtMDD are persistent or transient.
+ */
+
+ /// counts the number of references to the data object
+ unsigned int referenceCounter;
+};
+
+#include "qlparser/qtdata.icc"
+
+#endif
+
diff --git a/qlparser/qtdata.icc b/qlparser/qtdata.icc
new file mode 100644
index 0000000..677559e
--- /dev/null
+++ b/qlparser/qtdata.icc
@@ -0,0 +1,137 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline void
+QtData::setIteratorName( const std::string &iteratorNameNew )
+{
+ iteratorName = iteratorNameNew;
+}
+
+
+inline const std::string
+QtData::getIteratorName() const
+{
+ return iteratorName;
+}
+
+
+inline const QtData::QtLifetime
+QtData::getLifetime() const
+{
+ return persistent;
+}
+
+
+inline void
+QtData::setLifetime( QtLifetime flag)
+{
+ persistent = flag;
+}
+
+
+
+inline unsigned int
+QtData::getRefNo() const
+{
+ return referenceCounter;
+}
+
+
+
+inline ParseInfo
+QtData::getParseInfo()
+{
+ if( parseInfo )
+ return *parseInfo;
+ else
+ return ParseInfo();
+}
+
+
+inline void
+QtData::setParseInfo( const ParseInfo &info )
+{
+ if( parseInfo )
+ *parseInfo = info;
+ else
+ parseInfo = new ParseInfo( info );
+}
+
+
+
+inline
+int
+QtData::deleteRef()
+{
+ int objDeleted = 0;
+
+#if 0
+ if (parseInfo==NULL)
+ {
+ // RMInit::logOut << "QtData::deleteRef() - error: null parseinfo, resetting before doing delete." << endl;
+ parseInfo = new ParseInfo();
+ }
+#endif
+
+ if( !decRef() )
+ {
+ objDeleted = 1;
+ delete this;
+ }
+
+ return objDeleted;
+}
+
+
+
+inline
+unsigned int
+QtData::decRef()
+{
+ if( referenceCounter > 0 )
+ referenceCounter--;
+ else
+ RMInit::logOut << "Internal Error: QtData::decRef() - decrease of a zero reference counter" << endl;
+
+ return referenceCounter;
+}
+
+
+
+inline
+void
+QtData::incRef()
+{
+ referenceCounter++;
+}
+
+
+
+
+
diff --git a/qlparser/qtdelete.cc b/qlparser/qtdelete.cc
new file mode 100644
index 0000000..0b09179
--- /dev/null
+++ b/qlparser/qtdelete.cc
@@ -0,0 +1,268 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, QtDelete: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtdelete.cc,v 1.14 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtdelete.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtmddaccess.hh"
+#include "mddmgr/mddobj.hh"
+#include "mddmgr/mddcoll.hh"
+
+#include <iostream>
+
+
+
+const QtNode::QtNodeType QtDelete::nodeType = QtNode::QT_DELETE;
+
+
+
+QtDelete::QtDelete()
+ : QtExecute(), input(NULL)
+{
+}
+
+
+
+QtDelete::~QtDelete()
+{
+ if( input )
+ {
+ delete input;
+ input=NULL;
+ }
+}
+
+
+
+int
+QtDelete::evaluate()
+{
+ RMDBCLASS( "QtDelete", "evaluate()", "qlparser", __FILE__, __LINE__ )
+
+ QtNode::QtDataList* nextTupel=NULL;
+
+ // open input stream
+ try
+ {
+ input->open();
+ }
+ catch( ... )
+ {
+ input->close();
+ throw;
+ }
+
+ try
+ {
+ while( (nextTupel = input->next()) )
+ {
+ QtData* target = (*nextTupel)[0];
+
+ // check delete target
+ if( target->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtDelete::evaluate() - delete target must be an expression resulting in an r_Marray<>" << std::endl;
+
+ // delete tupel vector received by next()
+ vector<QtData*>::iterator dataIter;
+ for( dataIter=nextTupel->begin(); dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+
+ parseInfo.setErrorNo(951);
+ throw parseInfo;
+ }
+
+ QtMDD* targetMDD = (QtMDD*) target;
+ MDDObj* targetObj = targetMDD->getMDDObject();
+
+ // get leaf of ONC input
+ QtNodeList* leafList = input->getChilds( QtNode::QT_LEAF_NODES );
+ QtMDDAccess* inputLeaf = NULL;
+ // take the last QtMDDAccess object from the list assuming that it is the right one
+ for( std::list<QtNode*>::iterator iter=leafList->begin(); iter!=leafList->end(); iter++ )
+ if( (*iter)->getNodeType() == QT_MDD_ACCESS )
+ inputLeaf = (QtMDDAccess*)*iter;
+ delete leafList;
+ leafList=NULL;
+
+ // delete the MDD object
+ if( inputLeaf )
+ {
+ inputLeaf->getMDDColl()->remove( targetObj );
+ RMInit::logOut << "deleted..." << std::flush;
+ }
+
+ if(targetMDD && targetObj && !targetObj->isPersistent());
+ targetMDD->setLifetime( QtData::QT_TRANSIENT );
+
+ // delete tupel vector received by next()
+ vector<QtData*>::iterator dataIter;
+ for( dataIter=nextTupel->begin(); dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+ } // while
+
+ }
+ catch( ... )
+ {
+ input->close();
+ throw;
+ }
+
+ input->close();
+
+ return 0;
+}
+
+
+
+QtNode::QtNodeList*
+QtDelete::getChilds( QtChildType flag )
+{
+ QtNodeList* resultList=NULL;
+
+ if( input )
+ {
+ // allocate resultList
+ if( flag == QT_DIRECT_CHILDS );
+ resultList = new QtNodeList();
+
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ resultList = input->getChilds( flag );
+
+ // add the nodes of the current level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( input );
+ }
+ else
+ resultList = new QtNodeList();
+
+ return resultList;
+}
+
+
+
+void
+QtDelete::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtDelete Object" << std::endl;
+
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ {
+ if( input )
+ {
+ s << SPACE_STR(tab).c_str() << "input: " << std::endl;
+ input->printTree( tab+2, s, mode );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no input" << std::endl;
+
+ s << std::endl;
+ }
+}
+
+
+
+void
+QtDelete::printAlgebraicExpression( std::ostream& s )
+{
+ s << "delete";
+
+ if( input )
+ {
+ s << "( ";
+ input->printAlgebraicExpression( s );
+ s << " )";
+ }
+ else
+ s << "(<no input>)";
+}
+
+
+
+void
+QtDelete::setStreamInput( QtONCStream* newInput )
+{
+ input = newInput;
+ input->setParent( this );
+};
+
+QtONCStream::QtONCStream*
+QtDelete::getStreamInput()
+{
+ return input;
+}
+
+
+/*
+void
+QtDelete::preOptimize()
+{
+ if( input )
+ input->preOptimize();
+}
+*/
+
+
+void
+QtDelete::checkType()
+{
+ RMDBCLASS( "QtDelete", "checkType()", "qlparser", __FILE__, __LINE__ )
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input type
+ QtTypeTuple inputType = input->checkType();
+
+ if( inputType.tuple[0].getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtDelete::checkType() - delete target must be an expression resulting in an r_Marray<>" << std::endl;
+ parseInfo.setErrorNo(951);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtDelete::checkType() - operand branch invalid." << std::endl;
+
+}
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtdelete.hh b/qlparser/qtdelete.hh
new file mode 100644
index 0000000..c16f243
--- /dev/null
+++ b/qlparser/qtdelete.hh
@@ -0,0 +1,100 @@
+#ifndef __QTDELETE_HH__
+#define __QTDELETE_HH___
+
+#include "qlparser/qtexecute.hh"
+#include "qlparser/qtoncstream.hh"
+
+#include <iostream>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtDelete : public QtExecute
+{
+ public:
+ /// default constructor
+ QtDelete();
+
+ /// virtual destructor
+ virtual ~QtDelete();
+
+ /// method for evaluating the node
+ virtual int evaluate();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ ///
+ void setStreamInput( QtONCStream* newInput );
+ ///
+ /// returns input
+ QtONCStream* getStreamInput();
+ //@}
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// pre optimization
+// virtual void preOptimize();
+ /**
+ Pre-Optimization step is passed to the input streams.
+ */
+
+ /// type checking
+ virtual void checkType();
+
+ private:
+ /// one input stream
+ QtONCStream* input;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtdelete.icc"
+
+#endif
+
+
+
diff --git a/qlparser/qtdelete.icc b/qlparser/qtdelete.icc
new file mode 100644
index 0000000..db18e76
--- /dev/null
+++ b/qlparser/qtdelete.icc
@@ -0,0 +1,35 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtDelete::getNodeType() const
+{
+ return nodeType;
+}
+
diff --git a/qlparser/qtdomainoperation.cc b/qlparser/qtdomainoperation.cc
new file mode 100644
index 0000000..950c49d
--- /dev/null
+++ b/qlparser/qtdomainoperation.cc
@@ -0,0 +1,950 @@
+/*
+* 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, QtTrim: $Id: qtdomainoperation.cc,v 1.35 2002/06/15 20:16:42 coman Exp $";
+
+#include <vector>
+#include <string>
+using namespace std;
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtunaryoperation.hh"
+#include "qlparser/qtdomainoperation.hh"
+#include "qlparser/qtnode.hh"
+#include "qlparser/qtconst.hh"
+#include "qlparser/qtmintervaldata.hh"
+#include "qlparser/qtintervaldata.hh"
+#include "qlparser/qtpointdata.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtcomplexdata.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "tilemgr/tile.hh"
+
+#include "catalogmgr/ops.hh"
+#include "relcatalogif/mddbasetype.hh"
+#include "relcatalogif/ulongtype.hh"
+
+#include <iostream>
+
+
+const QtNode::QtNodeType QtDomainOperation::nodeType = QtNode::QT_DOMAIN_OPERATION;
+
+
+QtDomainOperation::QtDomainOperation( QtOperation* mintOp )
+ : mintervalOp( mintOp ),
+ dynamicMintervalExpression( true )
+{
+ RMDBCLASS( "QtDomainOperation", "QtDomainOperation( QtOperation* )", "qlparser", __FILE__, __LINE__ )
+
+ if( mintervalOp ) mintervalOp->setParent( this );
+}
+
+
+
+QtDomainOperation::QtDomainOperation( r_Minterval domainNew, const vector<bool>* newTrimFlags )
+ : mintervalOp(0),
+ dynamicMintervalExpression( false )
+{
+ RMDBCLASS( "QtDomainOperation", "QtDomainOperation( r_Minterval, const vector<bool>* )", "qlparser", __FILE__, __LINE__ )
+
+ // make a copy
+ vector<bool>* trimFlags = new vector<bool>( *newTrimFlags );
+ mintervalOp = new QtConst( new QtMintervalData( domainNew, trimFlags ) );
+ mintervalOp->setParent( this );
+}
+
+
+
+QtDomainOperation::~QtDomainOperation()
+{
+ RMDBCLASS( "QtDomainOperation", "~QtDomainOperation()", "qlparser", __FILE__, __LINE__ )
+
+ if( mintervalOp )
+ {
+ delete mintervalOp;
+ mintervalOp=NULL;
+ }
+}
+
+
+
+QtNode::QtNodeList*
+QtDomainOperation::getChilds( QtChildType flag )
+{
+ RMDBCLASS( "QtDomainOperation", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
+
+ QtNodeList* resultList=NULL;
+
+ resultList = QtUnaryOperation::getChilds( flag );
+
+ if( mintervalOp )
+ {
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ {
+ QtNodeList* subList;
+
+ subList = mintervalOp->getChilds( flag );
+
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ }
+
+ // add the nodes of the current level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( mintervalOp );
+ }
+
+ return resultList;
+}
+
+
+
+bool
+QtDomainOperation::equalMeaning( QtNode* node )
+{
+ RMDBCLASS( "QtDomainOperation", "equalMeaning( QtNode* )", "qlparser", __FILE__, __LINE__ )
+
+ bool result = false;
+
+ if( nodeType == node->getNodeType() )
+ {
+ QtDomainOperation* domainNode;
+ domainNode = (QtDomainOperation*) node; // by force
+
+ result = input->equalMeaning( domainNode->getInput() ) &&
+ mintervalOp->equalMeaning( domainNode->getMintervalOp() );
+ };
+
+ return ( result );
+}
+
+
+string
+QtDomainOperation::getSpelling()
+{
+ char tempStr[20];
+ sprintf(tempStr, "%ud", (unsigned long)getNodeType());
+ string result = string(tempStr);
+ result.append( mintervalOp->getSpelling() );
+ result.append( "(" );
+ result.append( input->getSpelling() );
+ result.append( ")" );
+
+ return result;
+}
+
+
+void
+QtDomainOperation::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ QtUnaryOperation::setInput( inputOld, inputNew );
+
+ if( mintervalOp == inputOld )
+ {
+ mintervalOp = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+};
+
+
+
+void
+QtDomainOperation::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtDomainOperation", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ // test, if there is already a specification for that dimension
+ bool trimming = false;
+
+ if( mintervalOp )
+ {
+ // pass optimization to minterval tree
+ mintervalOp->optimizeLoad( new QtNode::QtTrimList );
+
+ // evaluate minterval tree
+ QtData* operand = mintervalOp->evaluate(NULL);
+
+ // if spatial operation could be determined, it is static
+ dynamicMintervalExpression = !operand;
+
+ if( operand )
+ {
+ if( operand->getDataType() == QT_MINTERVAL )
+ {
+ r_Minterval domain = ((QtMintervalData*)operand)->getMintervalData();
+ vector<bool>* trimFlags = new vector<bool>( *(((QtMintervalData*)operand)->getTrimFlags()) );
+
+ if( trimList && trimList->empty() )
+ {
+ // no previous specification for that dimension
+ trimming = true;
+ for( int i=0; i!=domain.dimension(); i++ )
+ {
+ // create a new element
+ QtTrimElement* elem = new QtTrimElement;
+
+ elem->interval = domain[i];
+ elem->intervalFlag = (*trimFlags)[i];
+ elem->dimension = i;
+
+ // and add it to the list
+ trimList->push_back( elem );
+
+ trimming &= (*trimFlags)[i];
+ }
+ }
+ else
+ {
+ // previous specification exists, test for compatibility
+ }
+
+ if( trimFlags )
+ {
+ delete trimFlags;
+ trimFlags = NULL;
+ }
+ }
+
+ // else if( operand->getDataType() == QtData::QT_POINT )
+
+ // delete the operand
+ operand->deleteRef();
+ }
+ }
+
+ // pass optimization process to the input tree
+ if( input ) input->optimizeLoad( trimList );
+
+ // Eliminate node QtDomainOperation if only trimming occurs.
+ if( trimming )
+ {
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", "all trimming")
+
+ getParent()->setInput( this, input );
+
+ // Delete the node itself after resetting its input because
+ // otherwise the input is delete either.
+ setInput( input, NULL );
+ delete this;
+ }
+}
+
+
+
+QtData*
+QtDomainOperation::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtDomainOperation", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+
+ switch( input->getDataStreamType().getDataType() )
+ {
+ case QT_MDD:
+ {
+ if( mintervalOp->getDataStreamType().getDataType() == QT_POINT ||
+ mintervalOp->getDataStreamType().isInteger() )
+ {
+ //
+ // Projection to one cell.
+ //
+
+ QtData* indexData = mintervalOp->evaluate( inputList );
+
+ if( !indexData )
+ return 0;
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( indexData->getDataType() != QT_POINT &&
+ !indexData->getDataType().isInteger() )
+ {
+ RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - "
+ << "runtime type checking failed (QT_POINT, INTEGER)." << endl;
+
+ // delete index data
+ indexData->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ // get projection point
+ r_Point projPoint;
+
+ if( indexData->getDataType() == QT_POINT )
+ {
+ projPoint = ((QtPointData*)indexData)->getPointData();
+ }
+ else
+ {
+ projPoint = r_Point(1);
+
+ if( indexData->getDataType() == QT_SHORT ||
+ indexData->getDataType() == QT_OCTET ||
+ indexData->getDataType() == QT_LONG )
+ projPoint[0] = ((QtAtomicData*)indexData)->getSignedValue();
+ else
+ projPoint[0] = ((QtAtomicData*)indexData)->getUnsignedValue();
+
+ }
+
+ //
+ // In case of dynamic index expressions, load optimization has to
+ // be performed for the current input expression.
+ //
+ /*
+ if( dynamicMintervalExpression )
+ {
+ QtNode::QtTrimList* trimList = new QtNode::QtTrimList;
+
+ for( int i=0; i!=domain.dimension(); i++ )
+ {
+ // create a new element
+ QtTrimElement* elem = new QtTrimElement;
+
+ elem->interval = domain[i];
+ elem->intervalFlag = (*trimFlags)[i];
+ elem->dimension = i;
+
+ // and add it to the list
+ trimList->push_back( elem );
+ }
+
+ // pass optimization process to the input tree
+ input->optimizeLoad( trimList );
+ }
+ */
+
+ // get operand data
+ QtData* operand = input->evaluate( inputList );
+
+ if( !operand )
+ {
+ // delete indexData
+ indexData->deleteRef();
+
+ return 0;
+ }
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed (QT_MDD)." << endl;
+
+ // delete index and operand data
+ indexData->deleteRef();
+ operand ->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ QtMDD* qtMDD = (QtMDD*) operand;
+ MDDObj* currentMDDObj = qtMDD->getMDDObject();
+
+ if( currentMDDObj )
+ {
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " mdd domain: " << currentMDDObj->getCurrentDomain() )
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " mdd load domain: " << qtMDD->getLoadDomain() )
+
+ // reset loadDomain to intersection of domain and loadDomain
+ // if( domain.intersection_with( qtMDD->getLoadDomain() ) != qtMDD->getLoadDomain() )
+ // qtMDD->setLoadDomain( domain.intersection_with( qtMDD->getLoadDomain() ) );
+
+ // get type of cell
+ const BaseType* cellType = ((MDDBaseType*)(currentMDDObj->getMDDBaseType()))->getBaseType();
+
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " point access: " << projPoint )
+ const char* resultCell = NULL;
+ if (projPoint.dimension() == currentMDDObj->getDimension())
+ resultCell = currentMDDObj->pointQuery( projPoint );
+ if (resultCell == NULL)
+ {
+ RMInit::logOut << "Error: QtDomainOperation::evaluate() - projected cell is not defined." << endl;
+ parseInfo.setErrorNo(356);
+
+ // delete index and operand data
+ indexData->deleteRef();
+ operand ->deleteRef();
+
+ throw parseInfo;
+ }
+
+ // allocate cell buffer
+ char* resultBuffer = new char[ cellType->getSize() ];
+
+ // copy cell content
+ memcpy( (void*)resultBuffer, (void*)resultCell, cellType->getSize() );
+
+ // create data object for the cell
+ QtScalarData* scalarDataObj = NULL;
+ if( cellType->getType() == STRUCT )
+ scalarDataObj = new QtComplexData();
+ else
+ scalarDataObj = new QtAtomicData();
+
+ scalarDataObj->setValueType ( cellType );
+ scalarDataObj->setValueBuffer( resultBuffer );
+
+ // set return data object
+ returnValue = scalarDataObj;
+ }
+
+ // delete indexData
+ indexData->deleteRef();
+
+ // delete old operand
+ operand->deleteRef();
+
+ }
+ else // mintervalOp->getDataStreamType() == QT_MINTERVAL
+ {
+ //
+ // Trimming/Projection to an MDD object
+ //
+ QtData* indexData = mintervalOp->evaluate( inputList );
+
+ if( !indexData )
+ return 0;
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( indexData->getDataType() != QT_MINTERVAL )
+ {
+ RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - "
+ << "runtime type checking failed (QT_MINTERVAL)." << endl;
+
+ // delete index data
+ indexData->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ // get minterval data
+ vector<bool>* trimFlags = new vector<bool>( *(((QtMintervalData*)indexData)->getTrimFlags()) );
+ r_Minterval domain = ((QtMintervalData*)indexData)->getMintervalData();
+
+ //
+ // In case of dynamic index expressions, load optimization has to
+ // be performed for the current input expression.
+ //
+
+ if( dynamicMintervalExpression )
+ {
+ QtNode::QtTrimList* trimList = new QtNode::QtTrimList;
+
+ for( int i=0; i!=domain.dimension(); i++ )
+ {
+ // create a new element
+ QtTrimElement* elem = new QtTrimElement;
+
+ elem->interval = domain[i];
+ elem->intervalFlag = (*trimFlags)[i];
+ elem->dimension = i;
+
+ // and add it to the list
+ trimList->push_back( elem );
+ }
+
+ // pass optimization process to the input tree
+ input->optimizeLoad( trimList );
+ }
+
+ // get operand data
+ QtData* operand = input->evaluate( inputList );
+
+ if( !operand )
+ {
+ // delete index data
+ indexData->deleteRef();
+ return 0;
+ }
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed (QT_MDD)." << endl;
+
+ // delete index and operand data
+ indexData->deleteRef();
+ operand ->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ QtMDD* qtMDD = (QtMDD*) operand;
+ MDDObj* currentMDDObj = qtMDD->getMDDObject();
+
+ if( currentMDDObj )
+ {
+ bool trimming = false;
+ bool projection = false;
+
+ // reset loadDomain to intersection of domain and loadDomain
+ if( domain.intersection_with( qtMDD->getLoadDomain() ) != qtMDD->getLoadDomain() )
+ qtMDD->setLoadDomain( domain.intersection_with( qtMDD->getLoadDomain() ) );
+
+ // Test, if trimming has to be done; trimming = 1 if !(load domain is subset of spatial operation)
+ trimming = ( domain.intersection_with( qtMDD->getLoadDomain() ) == qtMDD->getLoadDomain() );
+
+ // Test, if a projection has to be made and build the projSet in projection case
+ set< r_Dimension, less<r_Dimension> > projSet;
+
+ for( int i=0; i<trimFlags->size(); i++ )
+ if( !(*trimFlags)[i] )
+ {
+ projection = true;
+ projSet.insert( i );
+ }
+
+ r_Minterval projectedDom( domain.dimension() - projSet.size() );
+
+ // build the projected domain
+ for( int i = 0; i < domain.dimension(); i++ )
+ // do not include dimensions projected away
+ if(projSet.find(i) == projSet.end())
+ projectedDom << domain[i];
+
+ if( trimFlags )
+ {
+ delete trimFlags;
+ trimFlags = NULL;
+ }
+
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " operation domain..: " << domain << " with projection " << projectedDom )
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " mdd load domain: " << qtMDD->getLoadDomain() )
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " mdd current domain: " << currentMDDObj->getCurrentDomain() )
+
+ if( trimming || projection )
+ {
+ // get relevant tiles
+ vector<Tile* >* relevantTiles = currentMDDObj->intersect( domain );
+
+ if( relevantTiles->size() > 0 )
+ {
+ // iterator for tiles
+ vector<Tile*>::iterator tileIt;
+
+ // create a transient MDD object for the query result
+ MDDObj* resultMDD = new MDDObj( currentMDDObj->getMDDBaseType(), projectedDom );
+
+ // and iterate over them
+ for( tileIt = relevantTiles->begin(); tileIt != relevantTiles->end(); tileIt++ )
+ {
+ // domain of the actual tile
+ r_Minterval tileDom = (*tileIt)->getDomain();
+
+ // domain of the relevant area of the actual tile
+ r_Minterval intersectDom = tileDom.create_intersection( domain );
+
+ RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " trimming/projecting tile with domain " << tileDom << " to domain " << intersectDom )
+
+ // create projected tile
+ Tile* resTile = new Tile( (*tileIt), intersectDom, &projSet );
+
+ // insert Tile in result mddObj
+ resultMDD->insertTile( resTile );
+ }
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)resultMDD );
+
+ // delete the tile vector
+ delete relevantTiles;
+ relevantTiles=NULL;
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtDomainOperation::evaluate() - the load domain does not intersect with tiles in the current MDD." << endl;
+ parseInfo.setErrorNo(356);
+
+ // delete index and operand data
+ indexData->deleteRef();
+ operand ->deleteRef();
+
+ throw parseInfo;
+ }
+
+ } // trimming || projection
+ else
+ // operand is passed through
+ returnValue = operand;
+
+ } // if( currentMDDObj )
+
+ // delete index and operand data
+ if( indexData ) indexData->deleteRef();
+ if( operand ) operand ->deleteRef();
+
+ }
+ break;
+ }
+ case QT_MINTERVAL:
+ {
+ QtData* operandData = NULL;
+ QtData* indexData = NULL;
+
+ operandData = input->evaluate( inputList );
+
+ if( operandData )
+ {
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operandData->getDataType() != QT_MINTERVAL )
+ {
+ RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed (QT_MINTERVAL)." << endl;
+ return 0;
+ }
+#endif
+ // get point
+ const r_Minterval& minterval = ((QtMintervalData*)operandData)->getMintervalData();
+
+ // get index
+ indexData = mintervalOp->evaluate( inputList );
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( indexData->getDataType() != QT_POINT && indexData->getDataType() != QT_CHAR &&
+ indexData->getDataType() != QT_USHORT && indexData->getDataType() != QT_ULONG )
+ {
+ RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed." << endl;
+ return 0;
+ }
+#endif
+ r_Dimension indexValue = 0;
+
+ switch( indexData->getDataType() )
+ {
+ case QT_POINT:
+ {
+ // get first element as index
+ const r_Point& indexPoint = ((QtPointData*)indexData)->getPointData();
+
+ if( indexPoint.dimension() != 1 )
+ {
+ RMInit::logOut << "Error: QtDomainOperation::evaluate() - Operand of minterval selection must be of type unsigned integer." << endl;
+ parseInfo.setErrorNo(397);
+
+ // delete ressources
+ if( operandData ) operandData->deleteRef();
+ if( indexData ) indexData ->deleteRef();
+
+ throw parseInfo;
+ }
+
+ indexValue = indexPoint[0];
+ }
+ break;
+
+ case QT_CHAR:
+ case QT_USHORT:
+ case QT_ULONG:
+ indexValue = ((QtAtomicData*)indexData)->getUnsignedValue();
+ break;
+
+ case QT_OCTET:
+ case QT_SHORT:
+ case QT_LONG:
+ indexValue = ((QtAtomicData*)indexData)->getSignedValue();
+ break;
+ default:
+ RMDBGONCE(0, RMDebug::module_qlparser, "r_QtDomainOperation", "evaluate() bad type " << indexData->getDataType());
+ break;
+ }
+//indexValue is a unsigned type -> there will never be a indexVAlue < 0
+ if( /*indexValue < 0 ||*/ indexValue >= minterval.dimension() )
+ {
+ RMInit::logOut << "Error: QtDomainOperation::evaluate() - index for minterval selection is out of range." << endl;
+ parseInfo.setErrorNo(398);
+
+ // delete ressources
+ if( operandData ) operandData->deleteRef();
+ if( indexData ) indexData ->deleteRef();
+
+ throw parseInfo;
+ }
+
+ returnValue = new QtIntervalData( minterval[indexValue] );
+ }
+
+ // delete ressources
+ if( operandData ) operandData->deleteRef();
+ if( indexData ) indexData ->deleteRef();
+ break;
+ }
+
+ case QT_POINT:
+ {
+ QtData* operandData = NULL;
+ QtData* indexData = NULL;
+
+ operandData = input->evaluate( inputList );
+
+ if( operandData )
+ {
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operandData->getDataType() != QT_POINT )
+ {
+ RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed (QT_POINT)." << endl;
+ return 0;
+ }
+#endif
+ // get point
+ const r_Point& pt = ((QtPointData*)operandData)->getPointData();
+
+ // get index
+ indexData = mintervalOp->evaluate( inputList );
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( indexData->getDataType() != QT_POINT && indexData->getDataType() != QT_CHAR &&
+ indexData->getDataType() != QT_USHORT && indexData->getDataType() != QT_ULONG )
+ {
+ RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed." << endl;
+ return 0;
+ }
+#endif
+ r_Dimension indexValue = 0;
+
+ switch( indexData->getDataType() )
+ {
+ case QT_POINT:
+ {
+ // get first element as index
+ const r_Point& indexPoint = ((QtPointData*)indexData)->getPointData();
+
+ if( indexPoint.dimension() != 1 )
+ {
+ RMInit::logOut << "Error: QtDomainOperation::evaluate() - Operand of point selection must be of type unsigned integer." << endl;
+ parseInfo.setErrorNo(399);
+
+ // delete ressources
+ if( operandData ) operandData->deleteRef();
+ if( indexData ) indexData ->deleteRef();
+
+ throw parseInfo;
+ }
+
+ indexValue = indexPoint[0];
+ }
+ break;
+
+ case QT_CHAR:
+ case QT_USHORT:
+ case QT_ULONG:
+ indexValue = ((QtAtomicData*)indexData)->getUnsignedValue();
+ break;
+
+ case QT_OCTET:
+ case QT_SHORT:
+ case QT_LONG:
+ indexValue = ((QtAtomicData*)indexData)->getSignedValue();
+ break;
+ default:
+ RMDBGONCE(0, RMDebug::module_qlparser, "r_QtDomainOperation", "evaluate() 2 - bad type " << indexData->getDataType());
+ break;
+ }
+
+ //indexValue is a unsigned type -> there will never be a indexValue < 0
+ if( /*indexValue < 0 ||*/ indexValue >= pt.dimension() )
+ {
+ RMInit::logOut << "Error: QtDomainOperation::evaluate() - index for point selection is out of range." << endl;
+ parseInfo.setErrorNo(411);
+
+ // delete ressources
+ if( operandData ) operandData->deleteRef();
+ if( indexData ) indexData ->deleteRef();
+
+ throw parseInfo;
+ }
+
+ returnValue = new QtAtomicData( (r_Long)pt[indexValue], 4 );
+ }
+
+ // delete ressources
+ if( operandData ) operandData->deleteRef();
+ if( indexData ) indexData ->deleteRef();
+ break;
+ }
+
+ default:
+ {
+ RMInit::logOut << "Error: QtDomainOperation::evaluate() - selection operation is not supported on this data type." << endl;
+ parseInfo.setErrorNo(396);
+ throw parseInfo;
+ }
+ }
+
+ return returnValue;
+}
+
+
+void
+QtDomainOperation::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtDomainOperation Object: type " << flush;
+ dataStreamType.printStatus( s );
+ s << endl;
+
+ if( mintervalOp )
+ {
+ s << SPACE_STR(tab).c_str() << "spatial operation: " << endl;
+ mintervalOp->printTree( tab + 2, s );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no spatial operation" << endl;
+
+ QtUnaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtDomainOperation::printAlgebraicExpression( ostream& s )
+{
+ s << "geo(";
+
+ if( mintervalOp )
+ mintervalOp->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ",";
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtTypeElement&
+QtDomainOperation::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtDomainOperation", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ //
+ // operation signatures
+ //
+ // MDD<T,D> x Minterval -> MDD<T,D>
+ // // MDD<T,D> x Interval -> MDD<T,D>
+ // MDD<T,D> x Point -> T
+ // MDD<T,D> x Integer -> T
+ // Minterval x Integer -> Interval
+ // Minterval x Point(1) -> Interval
+ // Point x Integer -> Integer
+ // Point x Point(1) -> Integer
+ //
+
+ // check operand branches
+ if( input && mintervalOp )
+ {
+
+ // 1. check input expression type
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ // 2. check index expression type
+ const QtTypeElement& indexType = mintervalOp->checkType( typeTuple );
+
+ // 3. determine result type
+ if( inputType.getDataType() == QT_MDD )
+ {
+ // check index type
+ if( indexType.getDataType() != QT_MINTERVAL
+ // && indexType.getDataType() != QT_INTERVAL
+ && indexType.getDataType() != QT_POINT
+ && !indexType.isInteger()
+ )
+ {
+ RMInit::logOut << "Error: QtDomainOperation::checkType() - spatial domain expressions must be either of type minterval, point, or integer." << endl;
+ parseInfo.setErrorNo(391);
+ throw parseInfo;
+ }
+
+ // MDD
+ if( indexType.getDataType() == QT_MINTERVAL /* || indexType.getDataType() == QT_INTERVAL */ )
+ // pass MDD type
+ dataStreamType = inputType;
+ else
+ // use MDD cell type
+ dataStreamType.setType( ((MDDBaseType*)inputType.getType())->getBaseType() );
+ }
+ else if( inputType.getDataType() == QT_MINTERVAL )
+ {
+ // check index type
+ if( !indexType.isInteger() && indexType.getDataType() != QT_POINT )
+ {
+ RMInit::logOut << "Error: QtDomainOperation::checkType() - Operand of minterval selection must be of type integer." << endl;
+ parseInfo.setErrorNo(397);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_INTERVAL );
+ }
+ else if( inputType.getDataType() == QT_POINT )
+ {
+ // check index type
+ if( !indexType.isInteger() && indexType.getDataType() != QT_POINT )
+ {
+ RMInit::logOut << "Error: QtDomainOperation::checkType() - Operand of point selection must be of type integer." << endl;
+ parseInfo.setErrorNo(399);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_ULONG );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtDomainOperation::checkType() - selection operation is not supported on this data type." << endl;
+ parseInfo.setErrorNo(396);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtDomainOperation::checkType() - input or index branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
diff --git a/qlparser/qtdomainoperation.hh b/qlparser/qtdomainoperation.hh
new file mode 100644
index 0000000..0806ca8
--- /dev/null
+++ b/qlparser/qtdomainoperation.hh
@@ -0,0 +1,124 @@
+#ifndef _QTDOMAINOPERATION_
+#define _QTDOMAINOPERATION_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtunaryoperation.hh"
+#include "qlparser/qtmintervaldata.hh"
+#include "raslib/sinterval.hh"
+#include "raslib/minterval.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+The class represents a spatial domain operation, e.g. trimming or projections.
+
+*/
+
+class QtDomainOperation : public QtUnaryOperation
+{
+ public:
+
+ /// constructor getting an minterval expression
+ QtDomainOperation( QtOperation* mintOp );
+
+ /// constructor
+ QtDomainOperation( r_Minterval domainNew, const vector<bool>* newTrimFlags );
+
+ /// destructor
+ virtual ~QtDomainOperation();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// test if the two nodes have an equal meaning in a subtree
+ virtual bool equalMeaning( QtNode* node );
+
+ /// creates a unique name for a common subexpression
+ virtual std::string getSpelling();
+
+ /// method for query rewrite
+ virtual void setInput( QtOperation* inputOld, QtOperation* inputNew );
+
+ /// optimizing load access
+ void optimizeLoad( QtTrimList* trimList );
+
+ /// evaluates the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+
+ ///
+ inline virtual void setInput( QtOperation* newInput );
+ ///
+ inline virtual void setMintervalOp(QtOperation* miop);
+ ///
+ inline QtOperation* getMintervalOp();
+
+ ///
+ //@}
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// pointer to an minterval expression
+ QtOperation* mintervalOp;
+
+ /// the flag determines if the minterval expression has to be calculated at runtime or not
+ bool dynamicMintervalExpression;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtdomainoperation.icc"
+
+#endif
+
diff --git a/qlparser/qtdomainoperation.icc b/qlparser/qtdomainoperation.icc
new file mode 100644
index 0000000..2541c7c
--- /dev/null
+++ b/qlparser/qtdomainoperation.icc
@@ -0,0 +1,66 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline void
+QtDomainOperation::setMintervalOp(QtOperation* miop)
+{
+ mintervalOp = miop;
+}
+
+inline QtOperation*
+QtDomainOperation::getMintervalOp()
+{
+ return mintervalOp;
+}
+
+
+inline const QtNode::QtNodeType
+QtDomainOperation::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline void
+QtDomainOperation::setInput( QtOperation* newInput )
+{
+ QtUnaryOperation::setInput( newInput );
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtexecute.hh b/qlparser/qtexecute.hh
new file mode 100644
index 0000000..94352ec
--- /dev/null
+++ b/qlparser/qtexecute.hh
@@ -0,0 +1,66 @@
+#ifndef __QTEXECUTE_HH__
+#define __QTEXECUTE_HH__
+
+#include "qlparser/qtnode.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtExecute : public QtNode
+{
+ public:
+ /// method for evaluating the execute node node
+ virtual int evaluate() = 0;
+
+ /// type checking
+ virtual void checkType() = 0;
+ /**
+ The method triggers type checking of the node's subtree. If an error occurs, an exception
+ is raised.
+ */
+};
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtinsert.cc b/qlparser/qtinsert.cc
new file mode 100644
index 0000000..bfcfbc5
--- /dev/null
+++ b/qlparser/qtinsert.cc
@@ -0,0 +1,361 @@
+/*
+* 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, QtInsert: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtinsert.cc,v 1.27 2003/12/27 20:40:21 rasdev Exp $";
+
+#include "qlparser/qtinsert.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtmdd.hh"
+
+#include "tilemgr/tile.hh"
+#include "mddmgr/mddcoll.hh"
+#include "mddmgr/mddobj.hh"
+
+#include <iostream>
+
+#include "servercomm/servercomm.hh"
+
+extern ServerComm::ClientTblElt* currentClientTblElt;
+
+const QtNode::QtNodeType QtInsert::nodeType = QtNode::QT_INSERT;
+
+
+QtInsert::QtInsert( const std::string& initCollectionName, QtOperation* initSource )
+ : QtExecute(), collectionName( initCollectionName ), source( initSource )
+{
+ source->setParent( this );
+}
+
+
+
+QtInsert::~QtInsert()
+{
+ if( source )
+ {
+ delete source;
+ source=NULL;
+ }
+}
+
+
+
+int
+QtInsert::evaluate()
+{
+ RMDBCLASS( "QtInsert", "evaluate()", "qlparser", __FILE__, __LINE__ )
+
+ // empty data list for evaluation of insert expression including constant
+ QtNode::QtDataList* nextTupel = new QtNode::QtDataList(0);
+
+ // get the operands
+ QtData* sourceData = source->evaluate( nextTupel );
+
+ if( sourceData )
+ {
+ QtMDD* sourceMDD = (QtMDD*) sourceData;
+ MDDObj* sourceObj = sourceMDD->getMDDObject();
+
+ MDDColl* persColl = NULL;
+ MDDColl* almost = NULL;
+
+ try
+ {
+ almost = MDDColl::getMDDCollection( collectionName.c_str() );
+ }
+ catch(...)
+ {
+
+ RMInit::logOut << "Error: QtInsert::evaluate() - collection name not found" << std::endl;
+
+ // delete the operand
+ if( sourceData ) sourceData->deleteRef();
+
+ parseInfo.setErrorNo(355);
+ throw parseInfo;
+ }
+if (!almost->isPersistent())
+ {
+ RMInit::logOut << "QtInsert: User tries to insert into system table" << std::endl;
+ if( sourceData ) sourceData->deleteRef();
+
+ parseInfo.setErrorNo(355);
+ throw parseInfo;
+ }
+else {
+ persColl = (MDDColl*)almost;
+ }
+
+ //
+ // check MDD and collection type for compatibility
+ //
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtInsert", \
+ char* collTypeStructure = persColl->getCollectionType()->getTypeStructure(); \
+ char* mddTypeStructure = sourceObj->getMDDBaseType()->getTypeStructure(); \
+ RMInit::dbgOut << std::endl << "Collection type structure.: " << collTypeStructure << std::endl \
+ << "MDD type structure........: " << mddTypeStructure << std::endl \
+ << "MDD domain................: " << sourceObj->getDefinitionDomain() << std::endl; \
+ free( collTypeStructure ); collTypeStructure=NULL; \
+ free( mddTypeStructure ); mddTypeStructure=NULL; )
+
+ // bug fix: "insert into" found claimed non-existing type mismatch -- PB 2003-aug-25, based on fix by K.Hahn
+ // if( !persColl->getCollectionType()->compatibleWith( (Type*) sourceObj->getMDDBaseType() ) )
+ if( !((MDDType*) sourceObj->getMDDBaseType())->compatibleWith( persColl->getCollectionType()->getMDDType() ) )
+ {
+ // free resources
+ persColl->releaseAll();
+ delete persColl;
+ persColl=NULL;
+ if( sourceData ) sourceData->deleteRef(); // delete the operand
+
+ // return error
+ RMInit::logOut << "Error: QtInsert::evaluate() - MDD and collection types are incompatible" << std::endl;
+ parseInfo.setErrorNo(959);
+ throw parseInfo;
+ }
+
+ if( !persColl->getCollectionType()->getMDDType()->compatibleWithDomain( &(sourceObj->getDefinitionDomain()) ) )
+ {
+ // free resources
+ persColl->releaseAll();
+ delete persColl;
+ persColl=NULL;
+ if( sourceData ) sourceData->deleteRef(); // delete the operand
+
+ // return error
+ RMInit::logOut << "Error: QtInsert::evaluate() - MDD and collection domains are incompatible" << std::endl;
+ parseInfo.setErrorNo(959);
+ throw parseInfo;
+ }
+
+ //
+ // convert a transient MDD object to a persistent one
+ //
+
+ // allocate a new oid within the current db
+ OId oid;
+#ifdef BASEDB_O2
+ if( !OId::allocateMDDOId( &oid ) )
+ {
+#else
+ OId::allocateOId( oid, OId::MDDOID );
+#endif
+ // get all tiles
+ vector<Tile*>* sourceTiles = sourceObj->getTiles();
+
+ // get a persistent type pointer
+ MDDBaseType* persMDDType = (MDDBaseType*)TypeFactory::ensurePersistence( (Type*)sourceObj->getMDDBaseType() );
+
+ if( !persMDDType )
+ {
+ RMInit::logOut << "Error: QtInsert::evaluate() - type not persistent" << std::endl;
+
+ // delete dynamic data
+ if( sourceData ) sourceData->deleteRef();
+ delete sourceTiles;
+ sourceTiles=NULL;
+ delete nextTupel;
+ nextTupel=NULL;
+ persColl->releaseAll();
+ delete persColl;
+ persColl=NULL;
+ parseInfo.setErrorNo(964);
+ throw parseInfo;
+ }
+
+ // create a persistent MDD object
+ // need a StorageLayout here
+ StorageLayout tempStorageLayout;
+ tempStorageLayout.setTileSize(StorageLayout::DefaultTileSize);
+ tempStorageLayout.setIndexType(StorageLayout::DefaultIndexType);
+ tempStorageLayout.setTilingScheme(StorageLayout::DefaultTilingScheme);
+ if (sourceObj->getDefinitionDomain().dimension() ==
+ StorageLayout::DefaultTileConfiguration.dimension())
+ tempStorageLayout.setTileConfiguration(StorageLayout::DefaultTileConfiguration);
+ MDDObj* persMDDObj = new MDDObj( persMDDType, sourceObj->getDefinitionDomain(), oid,
+ tempStorageLayout );
+
+ // iterate over source tiles
+ for( vector<Tile*>::iterator sourceIt = sourceTiles->begin(); sourceIt != sourceTiles->end(); sourceIt++ )
+ {
+ // create a new persistent tile, copy the transient data, and insert it into the target mdd object
+ Tile* newPersTile = new Tile( (*sourceIt)->getDomain(), persMDDType->getBaseType(), (*sourceIt)->getDataFormat() );
+ newPersTile->copyTile( (*sourceIt)->getDomain(), *sourceIt, (*sourceIt)->getDomain() );
+ persMDDObj->insertTile( newPersTile );
+ }
+
+ // delete tile vector
+ delete sourceTiles;
+ sourceTiles=NULL;
+ persColl->insert( persMDDObj );
+#ifdef BASEDB_O2
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtInsert::evaluate() - allocation of oid failed" << std::endl;
+
+ // delete dynamic data
+ if( sourceData ) sourceData->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+ persColl->releaseAll();
+ delete persColl;
+ persColl=NULL;
+ parseInfo.setErrorNo(958);
+ throw parseInfo;
+ }
+#else
+#endif
+ // free transient memory
+ persColl->releaseAll();
+ delete persColl;
+ persColl=NULL;
+ }
+ else
+ RMInit::logOut << "Error: QtInsert::evaluate() - insert data is invalid." << std::endl;
+
+ // delete source operand
+ if( sourceData ) sourceData->deleteRef();
+
+ // delete dummy tupel vector
+ delete nextTupel;
+ nextTupel=NULL;
+
+ return 0;
+}
+
+
+
+QtNode::QtNodeList*
+QtInsert::getChilds( QtChildType flag )
+{
+ QtNodeList* resultList=NULL;
+
+ RMDBGENTER(0, RMDebug::module_qlparser, "QtInsert", "QtInsert::getChilds()")
+
+ if( source )
+ {
+ // allocate resultList
+ if( flag == QT_DIRECT_CHILDS );
+ resultList = new QtNodeList();
+
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ resultList = source->getChilds( flag );
+
+ // add the nodes of the current level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( source );
+ }
+ else
+ resultList = new QtNodeList();
+
+
+ RMDBGEXIT(0, RMDebug::module_qlparser, "QtInsert", "QtInsert::getChilds()")
+ return resultList;
+}
+
+
+
+void
+QtInsert::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtInsert Object" << std::endl;
+
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ {
+ if( source )
+ {
+ s << SPACE_STR(tab).c_str() << "source : " << std::endl;
+ source->printTree( tab + 2, s );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no source" << std::endl;
+
+ s << std::endl;
+ }
+}
+
+
+
+void
+QtInsert::printAlgebraicExpression( std::ostream& s )
+{
+ s << "insert<";
+
+ if( source )
+ source->printAlgebraicExpression( s );
+ else
+ s << "<no source>";
+
+ s << ">";
+}
+
+
+QtOperation*
+QtInsert::getSource()
+{
+ return source;
+}
+
+
+/*
+void
+QtInsert::preOptimize()
+{
+ if( source )
+ source->optimizeLoad( new QtNode::QtTrimList );
+}
+*/
+
+
+void
+QtInsert::checkType()
+{
+ RMDBCLASS( "QtInsert", "checkType()", "qlparser", __FILE__, __LINE__ )
+
+ // check operand branches
+ if( source )
+ {
+
+ // get input type
+ const QtTypeElement& inputType = source->checkType();
+
+ if( inputType.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtInsert::checkType() - insert expression must be of type r_Marray<T>" << std::endl;
+ parseInfo.setErrorNo(960);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtInsert::checkType() - operand branch invalid." << std::endl;
+}
diff --git a/qlparser/qtinsert.hh b/qlparser/qtinsert.hh
new file mode 100644
index 0000000..5c928b9
--- /dev/null
+++ b/qlparser/qtinsert.hh
@@ -0,0 +1,104 @@
+#ifndef __QTINSERT_HH__
+#define __QTINSERT_HH___
+
+#include "qlparser/qtexecute.hh"
+#include "qlparser/qtoperation.hh"
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+#include <iostream>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/**
+
+*/
+
+class QtInsert : public QtExecute
+{
+ public:
+ /// constructor getting name of collection and insert expression
+ QtInsert( const std::string& initCollectionName, QtOperation* initSource );
+
+ /// virtual destructor
+ virtual ~QtInsert();
+
+ /// method for evaluating the node
+ virtual int evaluate();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method for query rewrite
+ inline virtual void setInput( QtOperation* child, QtOperation* input);
+
+ /// returns source
+ QtOperation* getSource();
+
+ /// pre optimization
+// virtual void preOptimize();
+ /**
+ Pre-Optimization step is passed to the input streams.
+ */
+
+ /// type checking
+ virtual void checkType();
+
+ private:
+ /// insert expression
+ QtOperation* source;
+
+ /// collection name
+ std::string collectionName;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtinsert.icc"
+
+#endif
+
+
+
diff --git a/qlparser/qtinsert.icc b/qlparser/qtinsert.icc
new file mode 100644
index 0000000..eb98e55
--- /dev/null
+++ b/qlparser/qtinsert.icc
@@ -0,0 +1,49 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtInsert::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline void
+QtInsert::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ if( inputOld == source )
+ {
+ source = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+};
+
+
diff --git a/qlparser/qtintervaldata.cc b/qlparser/qtintervaldata.cc
new file mode 100644
index 0000000..0d80cc2
--- /dev/null
+++ b/qlparser/qtintervaldata.cc
@@ -0,0 +1,128 @@
+/*
+* 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, QtIntervalData: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtintervaldata.cc,v 1.10 2005/09/03 20:17:55 rasdev Exp $";
+
+using namespace std;
+
+using namespace std;
+
+#include "qlparser/qtintervaldata.hh"
+
+#include <iostream>
+#include <cstring>
+
+
+QtIntervalData::QtIntervalData( const r_Sinterval& interval )
+ : intervalData(interval), QtData()
+{
+}
+
+
+
+QtDataType
+QtIntervalData::getDataType() const
+{
+ return QT_INTERVAL;
+}
+
+
+
+bool
+QtIntervalData::equal( const QtData* obj ) const
+{
+ int returnValue = false; // not equal by initialization
+
+ if( obj->getDataType() == QT_INTERVAL )
+ returnValue = (intervalData == ((QtIntervalData*)obj)->getIntervalData());
+
+ return returnValue;
+}
+
+
+
+std::string
+QtIntervalData::getSpelling() const
+{
+ std::string result;
+
+ // buffer
+ int bufferLen = 256; // on the save side for two integers plus colon
+ char* buffer = new char[ bufferLen ];
+ // replaced deprecated ostrstream -- PB 2005-jan-14
+ // ostrstream bufferStream( buffer, bufferLen );
+ ostringstream bufferStream( buffer );
+
+ bufferStream << intervalData << std::ends;
+
+ result.append( std::string( buffer ) );
+
+ delete[] buffer;
+ buffer = NULL;
+
+ return result;
+}
+
+
+
+char* QtIntervalData::getTypeStructure() const
+{
+ return strdup("interval");
+}
+
+
+
+void
+QtIntervalData::printStatus( std::ostream& stream ) const
+{
+ stream << "interval, value: " << intervalData << std::flush;
+ QtData::printStatus( stream );
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtintervaldata.hh b/qlparser/qtintervaldata.hh
new file mode 100644
index 0000000..af4f421
--- /dev/null
+++ b/qlparser/qtintervaldata.hh
@@ -0,0 +1,102 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#ifndef _QTINTERVALDATA_
+#define _QTINTERVALDATA_
+
+#include "qlparser/qtdata.hh"
+
+#include "raslib/sinterval.hh"
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include <iostream>
+// removed deprecated ostrstream -- PB 2005-jan-14
+// #include <strstream.h>
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+ The class encapsulates an interval.
+*/
+
+class QtIntervalData : public QtData
+{
+ public:
+ /// constructor getting the interval
+ QtIntervalData( const r_Sinterval& interval );
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ ///
+ inline const r_Sinterval& getIntervalData() const;
+ ///
+ inline void setIntervalData( const r_Sinterval& interval );
+
+ /// returns a null-terminated string describing the type structure
+ virtual char* getTypeStructure() const;
+ /**
+ The string pointer has to be free using free() by the caller.
+ */
+
+ ///
+ //@}
+
+ /// returns {\tt QT_INTERVAL}
+ virtual QtDataType getDataType() const;
+
+ /// compares data content
+ virtual bool equal( const QtData* obj ) const;
+
+ /// returns content dependent string representation
+ virtual std::string getSpelling() const;
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+
+ private:
+ /// prevents from using the default constructor
+ QtIntervalData(){};
+
+ ///
+ r_Sinterval intervalData;
+};
+
+#include "qlparser/qtintervaldata.icc"
+
+#endif
+
+
+
+
diff --git a/qlparser/qtintervaldata.icc b/qlparser/qtintervaldata.icc
new file mode 100644
index 0000000..46e32a1
--- /dev/null
+++ b/qlparser/qtintervaldata.icc
@@ -0,0 +1,42 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const r_Sinterval&
+QtIntervalData::getIntervalData() const
+{
+ return intervalData;
+}
+
+
+inline void
+QtIntervalData::setIntervalData( const r_Sinterval& interval )
+{
+ intervalData = interval;
+}
diff --git a/qlparser/qtintervalop.cc b/qlparser/qtintervalop.cc
new file mode 100644
index 0000000..d5884cc
--- /dev/null
+++ b/qlparser/qtintervalop.cc
@@ -0,0 +1,311 @@
+/*
+* 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, QtIntervalOp: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtintervalop.cc,v 1.13 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtintervalop.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtintervaldata.hh"
+#include "qlparser/qtstringdata.hh"
+#include "qlparser/qtatomicdata.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+
+const QtNode::QtNodeType QtIntervalOp::nodeType = QT_INTERVALOP;
+
+QtIntervalOp::QtIntervalOp( QtOperation* initInput1, QtOperation* initInput2 )
+ : QtBinaryOperation( initInput1, initInput2 )
+{
+}
+
+
+
+bool
+QtIntervalOp::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+QtData*
+QtIntervalOp::evaluate( QtDataList* inputList )
+{
+ QtData* returnValue = NULL;
+ QtData* operand1 = NULL;
+ QtData* operand2 = NULL;
+
+ if( getOperands( inputList, operand1, operand2 ) )
+ {
+ r_Sinterval sinterval;
+
+ switch( operand1->getDataType() )
+ {
+ case QT_LONG:
+ case QT_SHORT:
+ case QT_OCTET:
+ try{
+ sinterval.set_low( (r_Range)(((QtAtomicData*)operand1)->getSignedValue()) );
+ }
+ catch(...)
+ {
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be of type integer or '*'." << endl;
+ parseInfo.setErrorNo(389);
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ throw parseInfo;
+ }
+ break;
+
+ case QT_ULONG:
+ case QT_USHORT:
+ case QT_CHAR:
+ try{
+ sinterval.set_low( (r_Range)((QtAtomicData*)operand1)->getUnsignedValue() );
+ }
+ catch(...)
+ {
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be of type integer or '*'." << endl;
+ parseInfo.setErrorNo(389);
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ throw parseInfo;
+ }
+ break;
+
+ case QT_STRING:
+ QtStringData *p;
+ p = dynamic_cast<QtStringData *>(operand1);
+
+ if (p && (p->getStringData() == string("*")) )
+ sinterval.set_low('*');
+ else
+ {
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be '*'." << endl;
+ parseInfo.setErrorNo(389);
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ throw parseInfo;
+ }
+ break;
+
+ default:
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be of type integer or '*'." << endl;
+ parseInfo.setErrorNo(388);
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ throw parseInfo;
+ }
+
+
+ switch( operand2->getDataType() )
+ {
+ case QT_LONG:
+ case QT_SHORT:
+ case QT_OCTET:
+ try{
+ sinterval.set_high( (r_Range)(((QtAtomicData*)operand2)->getSignedValue()) );
+ }
+ catch(...)
+ {
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be of type integer or '*'." << endl;
+ parseInfo.setErrorNo(389);
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ throw parseInfo;
+ }
+ break;
+
+ case QT_ULONG:
+ case QT_USHORT:
+ case QT_CHAR:
+ try{
+ sinterval.set_high( (r_Range)((QtAtomicData*)operand2)->getUnsignedValue() );
+ }
+ catch(...)
+ {
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be of type integer or '*'." << endl;
+ parseInfo.setErrorNo(389);
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ throw parseInfo;
+ }
+ break;
+
+ case QT_STRING:
+ QtStringData *p;
+ p = dynamic_cast<QtStringData *>(operand2);
+
+ if (p && (p->getStringData() == string("*")) )
+ sinterval.set_high('*');
+ else
+ {
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be '*'." << endl;
+ parseInfo.setErrorNo(389);
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ throw parseInfo;
+ }
+ break;
+
+ default:
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be of type integer or '*'." << endl;
+ parseInfo.setErrorNo(388);
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+
+ throw parseInfo;
+ }
+
+ returnValue = new QtIntervalData( sinterval );
+
+ // delete the old operands
+ if( operand1 ) operand1->deleteRef();
+ if( operand2 ) operand2->deleteRef();
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtIntervalOp::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtIntervalOp Object " << getNodeType() << endl;
+
+ QtBinaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtIntervalOp::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ":";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtTypeElement&
+QtIntervalOp::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtIintervalOp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input1 && input2 )
+ {
+
+ const QtTypeElement& input1Type = input1->checkType( typeTuple );
+ const QtTypeElement& input2Type = input2->checkType( typeTuple );
+
+ bool opTypesValid = true;
+
+ // check operand1
+ opTypesValid &= input1Type.getDataType() == QT_STRING ||
+ input1Type.getDataType() == QT_LONG ||
+ input1Type.getDataType() == QT_SHORT ||
+ input1Type.getDataType() == QT_OCTET ||
+ input1Type.getDataType() == QT_ULONG ||
+ input1Type.getDataType() == QT_USHORT ||
+ input1Type.getDataType() == QT_CHAR;
+
+ // check operand2
+ opTypesValid &= input2Type.getDataType() == QT_STRING ||
+ input2Type.getDataType() == QT_LONG ||
+ input2Type.getDataType() == QT_SHORT ||
+ input2Type.getDataType() == QT_OCTET ||
+ input2Type.getDataType() == QT_ULONG ||
+ input2Type.getDataType() == QT_USHORT ||
+ input2Type.getDataType() == QT_CHAR;
+
+ if( !opTypesValid )
+ {
+ RMInit::logOut << "Error: QtIntervalOp::evaluate() - interval bound must be of type integer or '*'." << endl;
+ parseInfo.setErrorNo(389);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_INTERVAL );
+ }
+ else
+ RMInit::logOut << "Error: QtIntervalOp::checkType() - input branch invalid." << endl;
+
+ return dataStreamType;
+}
diff --git a/qlparser/qtintervalop.hh b/qlparser/qtintervalop.hh
new file mode 100644
index 0000000..de43b78
--- /dev/null
+++ b/qlparser/qtintervalop.hh
@@ -0,0 +1,84 @@
+#ifndef _QTINTERVALOP_
+#define _QTINTERVALOP_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtbinaryoperation.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the root of an interval expression.
+
+*/
+
+class QtIntervalOp : public QtBinaryOperation
+{
+ public:
+ /// constructor getting the two operands
+ QtIntervalOp( QtOperation* input1, QtOperation* input2 );
+
+ /// returns FALSE saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+#include "qlparser/qtintervalop.icc"
+
+#endif
+
diff --git a/qlparser/qtintervalop.icc b/qlparser/qtintervalop.icc
new file mode 100644
index 0000000..331e0f0
--- /dev/null
+++ b/qlparser/qtintervalop.icc
@@ -0,0 +1,34 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtIntervalOp::getNodeType() const
+{
+ return nodeType;
+}
diff --git a/qlparser/qtiterator.cc b/qlparser/qtiterator.cc
new file mode 100644
index 0000000..ef0615f
--- /dev/null
+++ b/qlparser/qtiterator.cc
@@ -0,0 +1,260 @@
+/*
+* 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, QtIterator: $Id: qtiterator.cc,v 1.20 2001/08/14 10:48:17 rastest Exp $";
+
+#include "qlparser/qtiterator.hh"
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+const QtNode::QtNodeType QtIterator::nodeType = QtNode::QT_ITERATOR;
+
+QtIterator::QtIterator()
+ : QtONCStream(),
+ inputs(NULL)
+{
+}
+
+
+QtIterator::QtIterator( QtNode* node )
+ : QtONCStream( node ),
+ inputs(NULL)
+{
+}
+
+
+QtIterator::~QtIterator()
+{
+ if( inputs )
+ {
+ // delete the inputs
+ for( int i=0; i<inputs->size(); i++ )
+ {
+ delete (*inputs)[i];
+ (*inputs)[i] = NULL;
+ }
+
+ // delete the list
+ delete inputs;
+ inputs=NULL;
+ }
+}
+
+
+QtNode::QtNodeList*
+QtIterator::getChilds( QtChildType flag )
+{
+ QtNodeList* resultList=NULL;
+ list<QtNode*>::iterator it; //default
+ QtNode::QtNodeList::iterator iter;
+
+ RMDBCLASS( "QtIterator", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
+
+ // allocate resultList
+ resultList = new QtNodeList();
+
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ {
+ for(int i=0; i<inputs->size(); i++ )
+ {
+ QtNodeList* subList=NULL;
+ subList = (*inputs)[i]->getChilds( flag );
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ };
+ };
+
+ // add the nodes of the current level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ for(int i=0; i<inputs->size(); i++ )
+ resultList->push_back( (*inputs)[i] );
+
+ return resultList;
+}
+
+
+void
+QtIterator::open()
+{
+ RMDBCLASS( "QtIterator", "open()", "qlparser", __FILE__, __LINE__ )
+
+ if( inputs )
+ {
+ QtONCStreamList::iterator i;
+
+ for( i=inputs->begin(); i!=inputs->end(); i++ )
+ (*i)->open();
+ }
+}
+
+
+void
+QtIterator::close()
+{
+ RMDBCLASS( "QtIterator", "close()", "qlparser", __FILE__, __LINE__ )
+
+ if( inputs )
+ {
+ QtONCStreamList::iterator i;
+
+ for( i=inputs->begin(); i!=inputs->end(); i++ )
+ (*i)->close();
+ }
+}
+
+
+void
+QtIterator::reset()
+{
+ if( inputs )
+ {
+ QtONCStreamList::iterator i;
+
+ for( i=inputs->begin(); i!=inputs->end(); i++ )
+ (*i)->reset();
+ }
+}
+
+
+void
+QtIterator::printTree( int tab, ostream& s, QtChildType mode )
+{
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ {
+ if( inputs )
+ for( int i=0; i<inputs->size(); i++ )
+ {
+ s << SPACE_STR(tab).c_str() << "input " << i+1 << ": " << endl;
+ (*inputs)[i]->printTree( tab+2, s, mode );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no inputs" << endl;
+
+ s << endl;
+ }
+}
+
+
+
+void
+QtIterator::printAlgebraicExpression( ostream& s )
+{
+ if( inputs )
+ {
+ s << "( ";
+
+ for( int i=0; i<inputs->size(); i++ )
+ {
+ (*inputs)[i]->printAlgebraicExpression( s );
+
+ if( i < inputs->size()-1 )
+ s << ", ";
+ }
+
+ s << " )";
+ }
+ else
+ s << "(<no input>)";
+}
+
+
+
+void
+QtIterator::setStreamInput( QtONCStream* oldInput, QtONCStream* newInput )
+{
+ QtONCStreamList::iterator iter;
+ bool notDone=true;
+
+ for( iter=inputs->begin(); iter!=inputs->end() && notDone; iter++ )
+ if( *iter && (*iter) == oldInput )
+ {
+ *iter = newInput;
+ if( newInput )
+ newInput->setParent( this );
+
+ notDone = false;
+ }
+
+ if( notDone )
+ RMInit::logOut << "QtIterator::setStreamInput() - Error: Old input stream not found." << endl;
+}
+
+QtIterator::QtONCStreamList*
+QtIterator::getStreamInputs()
+{
+ return inputs;
+}
+
+/*
+void
+QtIterator::preOptimize()
+{
+ if( inputs )
+ {
+ QtONCStreamList::iterator i;
+
+ for( i=inputs->begin(); i!=inputs->end(); i++ )
+ (*i)->preOptimize();
+ }
+}
+*/
+
+
+void
+QtIterator::getInputTypeTuple( QtTypeTuple& typeTuple )
+{
+ typeTuple = QtTypeTuple(0);
+
+ if( inputs )
+ {
+ QtONCStreamList::iterator inputIter;
+
+ for( inputIter=inputs->begin(); inputIter!=inputs->end(); inputIter++ )
+ {
+ if( *inputIter )
+ typeTuple.concat( (*inputIter)->checkType() );
+ else
+ RMInit::logOut << "Error: QtIterator::getInputTypeTuple() - input branch is invalid." << endl;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtIterator::getInputTypeTuple() - inputs branch is invalid." << endl;
+}
+
diff --git a/qlparser/qtiterator.hh b/qlparser/qtiterator.hh
new file mode 100644
index 0000000..d2fad41
--- /dev/null
+++ b/qlparser/qtiterator.hh
@@ -0,0 +1,118 @@
+/*
+* 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>.
+*/
+#ifndef _QTITERATOR_
+#define _QTITERATOR_
+
+#include "qlparser/qtoncstream.hh"
+
+#include <vector>
+
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+It is super class for every class capable of iterating over collections of MDD.
+It has a list of inputs of type QtONCStream, so every instance of type
+QtONCStream or of a subtype of it can serve as an input stream for a QtIterator
+object. The input streams can be combined differently, as cross product of the
+inputs in class QtSelectionIterator or as simple tupels in the order they occure
+in the input streams in class QtOperationIterator.
+
+*/
+
+class QtIterator : public QtONCStream
+{
+ public:
+ /// list of QtONCStream objects
+ typedef std::vector<QtONCStream*> QtONCStreamList;
+
+ /// default constructor
+ QtIterator();
+
+ /// constructor getting a pointer to the parent
+ QtIterator( QtNode* node );
+
+ /// destructor
+ virtual ~QtIterator();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: Operations of the ONC protocol
+ //@{
+ ///
+ virtual void open();
+ ///
+ virtual void close();
+ ///
+ virtual void reset();
+ //@}
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ inline void setStreamInputs( QtONCStreamList* inputs );
+
+ /// Returns inputs
+ QtONCStreamList* getStreamInputs();
+ /// exchange the stream input {\tt oldInput} with {\tt newInput}
+ void setStreamInput( QtONCStream* oldInput, QtONCStream* newInput );
+ ///
+ //inline virtual void setParents();
+ //@}
+
+ /// pre optimization
+ //virtual void preOptimize();
+ /**
+ Pre-Optimization step is passed to the input streams.
+ */
+
+ /// get input type tuple
+ void getInputTypeTuple( QtTypeTuple& typeTuple );
+
+ protected:
+ /// list of input streams
+ QtONCStreamList* inputs;
+
+ private:
+ /// atribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtiterator.icc"
+
+#endif
+
diff --git a/qlparser/qtiterator.icc b/qlparser/qtiterator.icc
new file mode 100644
index 0000000..ede86ed
--- /dev/null
+++ b/qlparser/qtiterator.icc
@@ -0,0 +1,36 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline void
+QtIterator::setStreamInputs( QtONCStreamList* inputsNew )
+{
+ inputs = inputsNew;
+ for( int i=0; i<inputs->size(); i++ )
+ (*inputs)[i]->setParent( this );
+};
diff --git a/qlparser/qtjoiniterator.cc b/qlparser/qtjoiniterator.cc
new file mode 100644
index 0000000..12277ab
--- /dev/null
+++ b/qlparser/qtjoiniterator.cc
@@ -0,0 +1,338 @@
+/*
+* 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:
+ *
+ ************************************************************/
+
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtjoiniterator.hh"
+#include "qlparser/qtmdd.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+const QtNode::QtNodeType QtJoinIterator::nodeType = QtNode::QT_JOIN_ITERATOR;
+
+
+QtJoinIterator::QtJoinIterator()
+ : QtIterator(),
+ actualTupel(NULL),
+ outputStreamIsEmpty(false)
+{
+}
+
+
+QtJoinIterator::QtJoinIterator( QtNode* node )
+ : QtIterator( node ),
+ actualTupel(NULL),
+ outputStreamIsEmpty(false)
+{
+}
+
+
+QtJoinIterator::~QtJoinIterator()
+{
+ vector<QtData*>::iterator i; //default
+
+ if( actualTupel )
+ {
+ // first delete still existing data carriers
+ for( QtDataList::iterator iter=actualTupel->begin(); iter!=actualTupel->end(); iter++ )
+ if( *iter ) (*iter)->deleteRef();
+
+ delete actualTupel;
+ actualTupel=NULL;
+ }
+}
+
+
+void
+QtJoinIterator::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtJoinIterator Object: type " << flush;
+ dataStreamType.printStatus( s );
+ s << endl;
+
+ QtIterator::printTree( tab, s, mode );
+}
+
+
+
+void
+QtJoinIterator::printAlgebraicExpression( ostream& s )
+{
+ s << "join";
+
+ QtIterator::printAlgebraicExpression( s );
+}
+
+
+void
+QtJoinIterator::open()
+{
+ RMDBCLASS( "QtJoinIterator", "open()", "qlparser", __FILE__, __LINE__ )
+
+ QtIterator::open();
+
+ outputStreamIsEmpty = false; // initialization
+
+ if( inputs )
+ {
+ // The idea of actualTupel initialization:
+ //
+ // tupel[0] tupel[1] tupel[2] ... |
+ // -----------------------------------------------------
+ // 0 0 0 | initial phase
+ // 0 b1 c1 | open
+ // a1 b1 c1 | next invocation
+ // a2 b1 c1 | "
+ // a1 b2 c1 | "
+ // : : : | "
+
+ // allocate an empty tupel, right now each input stream provides one data element
+ actualTupel = new QtDataList( inputs->size() );
+
+ // set the first element of the tupel to NULL
+ (*actualTupel)[0] = NULL;
+
+ // fill the tupel, except of the first element, with the first elements of the input streams
+ //the first element is filled in the ::next() method
+ for( int tupelPos=1; tupelPos<actualTupel->size(); tupelPos++ )
+ {
+ QtDataList* resultList = (*inputs)[tupelPos]->next();
+
+ if( resultList )
+ {
+ // take the first data element of the input stream result
+ (*actualTupel)[tupelPos] = (*resultList)[0];
+
+ // delete the result vector (only the first data carriers is taken, the others are never deleted)
+ delete resultList;
+ resultList = NULL;
+ }
+ else
+ {
+ // In that case, one of the input streams is empty. Therefore, the output stream of
+ // the self object is empty either.
+ (*actualTupel)[tupelPos] = NULL;
+ outputStreamIsEmpty = true;
+ }
+ }
+
+ // Reset the first stream again, because the first tupel element is catched when next() is
+ // called for the first time.
+ // (*inputs)[0]->reset();
+ }
+}
+
+
+QtNode::QtDataList*
+QtJoinIterator::next()
+{
+ RMDBCLASS( "QtJoinIterator", "next()", "qlparser", __FILE__, __LINE__ )
+
+
+ QtDataList* returnValue = NULL;
+
+ if( inputs && actualTupel && !outputStreamIsEmpty )
+ {
+ bool nextTupelAvailable = true;
+ bool nextTupelValid = false;
+ int tupelPos;
+ QtDataList* resultList = NULL;
+ QtONCStreamList::iterator iter;
+
+ while( !nextTupelValid && nextTupelAvailable && !outputStreamIsEmpty )
+ {
+ // switch to the next tupel which means
+
+ nextTupelAvailable = false;
+ tupelPos = 0;
+ iter = inputs->begin();
+
+ while( !nextTupelAvailable && iter!=inputs->end() )
+ {
+ resultList = (*iter)->next();
+
+ // Test, if the first input stream is empty, because this is not tested in open()
+ if( resultList == NULL && tupelPos==0 && (*actualTupel)[0] == 0 )
+ outputStreamIsEmpty = true;
+
+ if( resultList == NULL )
+ {
+ (*iter)->reset(); // reset the stream ...
+ //this causes the first element of the list to be deleted - not the others
+ resultList = (*iter)->next(); // ... and read the first element again
+ // this was commented out because it will cause problems when the stream is closed
+ // if it is commented out it will break join queries
+ }
+ else
+ nextTupelAvailable = true;
+
+ //
+ // exchange the actual element in the tupel
+ //
+
+ // delete the data carrier
+ if( (*actualTupel)[tupelPos] )
+ {
+ (*actualTupel)[tupelPos]->deleteRef();
+ (*actualTupel)[tupelPos] = NULL;
+ }
+
+ if( resultList )
+ {
+ // take the first data element of the input stream result - copy the data carrier pointer
+ (*actualTupel)[tupelPos] = (*resultList)[0];
+
+ // delete the result vector (only the first data carrier is taken, the others are never deleted)
+ delete resultList;
+ resultList = NULL;
+ }
+
+ iter++;
+ tupelPos++;
+ }
+
+ if( nextTupelAvailable )
+ nextTupelValid = true;
+ }
+
+ if( nextTupelAvailable )
+ {
+ // Copy the actual tupel in order to pass it as the next stream element
+ // which means increase references to data elements.
+ returnValue = new QtDataList( actualTupel->size() );
+
+ for( tupelPos=0; tupelPos < actualTupel->size(); tupelPos++ )
+ if( (*actualTupel)[tupelPos] )
+ {
+ (*returnValue)[tupelPos] = (*actualTupel)[tupelPos];
+ (*actualTupel)[tupelPos]->incRef();
+ }
+ else
+ {
+ // should not come here, because now the next tupel isn't valid
+
+ // delete return value again
+ for( tupelPos=0; tupelPos < returnValue->size(); tupelPos++ )
+ if( (*returnValue)[tupelPos] )
+ (*returnValue)[tupelPos]->deleteRef();
+
+ delete returnValue;
+ returnValue = NULL;
+
+ RMInit::logOut << "Internal Error in QtJoinIterator::next()" << endl;
+ }
+ }
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtJoinIterator::close()
+{
+ RMDBCLASS( "QtJoinIterator", "close()", "qlparser", __FILE__, __LINE__ )
+
+ if( actualTupel )
+ {
+ // first delete still existing data carriers
+ for( QtDataList::iterator iter=actualTupel->begin(); iter!=actualTupel->end(); iter++ )
+ if( *iter ) (*iter)->deleteRef();
+
+ delete actualTupel;
+ actualTupel = NULL;
+ }
+
+ QtIterator::close();
+}
+
+
+void
+QtJoinIterator::reset()
+{
+ RMDBCLASS( "QtJoinIterator", "reset()", "qlparser", __FILE__, __LINE__ )
+
+ // reset the input streams
+ QtIterator::reset();
+
+ if( inputs )
+ {
+ // first delete still existing data carriers
+ for( QtDataList::iterator iter=actualTupel->begin(); iter!=actualTupel->end(); iter++ )
+ if( *iter )
+ {
+ (*iter)->deleteRef();
+ (*iter) = NULL;
+ }
+
+ // fill the tupel with the first elements of the input streams except of the first element
+ for( int tupelPos=1; tupelPos<actualTupel->size(); tupelPos++ )
+ {
+ QtDataList* resultList = (*inputs)[tupelPos]->next();
+
+ if( resultList )
+ {
+ // take the first data element of the input stream result
+ (*actualTupel)[tupelPos] = (*resultList)[0];
+
+ // delete the result vector (only the first data carriers is taken, the others are never deleted)
+ delete resultList;
+ resultList = NULL;
+ }
+ else
+ (*actualTupel)[tupelPos] = NULL;
+
+ }
+
+ (*actualTupel)[0] = NULL; // fist tupel element is catched when next() is called for the first time
+ }
+}
+
+
+
+const QtTypeTuple&
+QtJoinIterator::checkType()
+{
+ RMDBCLASS( "QtJoinIterator", "checkType()", "qlparser", __FILE__, __LINE__ )
+
+ getInputTypeTuple( dataStreamType );
+
+ return dataStreamType;
+}
diff --git a/qlparser/qtjoiniterator.hh b/qlparser/qtjoiniterator.hh
new file mode 100644
index 0000000..ca1403f
--- /dev/null
+++ b/qlparser/qtjoiniterator.hh
@@ -0,0 +1,120 @@
+#ifndef _QTJOINITERATOR_
+#define _QTJOINITERATOR_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtiterator.hh"
+#include "qlparser/qtoperation.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+An object of this class takes its inputs and computes a tupel for every element
+of the cross product. The result is passed to the output stream.
+The class represents the FROM part of a query.
+
+*/
+
+class QtJoinIterator : public QtIterator
+{
+ public:
+ /// default constructor
+ QtJoinIterator();
+
+ /// constructor getting a pointer to the parent
+ QtJoinIterator( QtNode* node );
+
+ /// virtual destructor
+ virtual ~QtJoinIterator();
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: Operations of the ONC protocol:
+ //@{
+ ///
+ void open();
+ ///
+ QtDataList* next();
+ /**
+ According to the producer/consumer protocol of ONC streams, the {/tt next()}
+ method has to store the last tupel of the crossproduct and update it with a new
+ element everytime it is invoked. Than it makes a copy of the tupel and pass
+ it to the caller.
+ */
+ ///
+ void close();
+ ///
+ void reset();
+ ///
+ //@}
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ //inline virtual void setParents();
+ //@}
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking
+ virtual const QtTypeTuple& checkType();
+
+ private:
+ /// inidicates if the output stream is empty or not
+ bool outputStreamIsEmpty;
+ /** The output stream is empty if at least one of the input streams is empty.
+ In that case, the cross product has no elements. This is indicated
+ by the variable {\tt outputStreamIsEmpty} which is set in the method
+ {\tt open()}.
+ */
+
+ /// pointer to a copy of the last passed tupel
+ QtDataList* actualTupel;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtjoiniterator.icc"
+
+#endif
+
diff --git a/qlparser/qtjoiniterator.icc b/qlparser/qtjoiniterator.icc
new file mode 100644
index 0000000..741c048
--- /dev/null
+++ b/qlparser/qtjoiniterator.icc
@@ -0,0 +1,35 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtJoinIterator::getNodeType() const
+{
+ return nodeType;
+}
+
diff --git a/qlparser/qtmarrayop.cc b/qlparser/qtmarrayop.cc
new file mode 100644
index 0000000..dbcbc84
--- /dev/null
+++ b/qlparser/qtmarrayop.cc
@@ -0,0 +1,314 @@
+/*
+* 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, QtMarrayOp: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtmarrayop.cc,v 1.19 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtmarrayop.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtpointdata.hh"
+#include "qlparser/qtmintervaldata.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "tilemgr/tile.hh"
+
+#include "catalogmgr/typefactory.hh"
+
+#include "catalogmgr/algebraops.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+
+const QtNode::QtNodeType QtMarrayOp::nodeType = QT_MARRAYOP;
+
+QtMarrayOp::QtMarrayOp( const string &initIteratorName, QtOperation* mintervalExp, QtOperation* cellExp )
+ : iteratorName( initIteratorName ), QtBinaryOperation( mintervalExp, cellExp )
+{
+}
+
+
+
+void
+QtMarrayOp::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtMarrayOp", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ // delete the trimList and optimize subtrees
+
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ QtBinaryOperation::optimizeLoad( new QtNode::QtTrimList() );
+}
+
+
+
+bool
+QtMarrayOp::isCommutative() const
+{
+ return false; // NOT commutative
+}
+
+
+
+QtData*
+QtMarrayOp::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtMarrayOp", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand1 = NULL;
+
+ if( getOperand( inputList, operand1, 1 ) )
+ {
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand1->getDataType() != QT_MINTERVAL )
+ RMInit::logOut << "Internal error in QtMarrayOp::evaluate() - "
+ << "runtime type checking failed (Minterval)." << endl;
+
+ // delete old operand
+ if( operand1 ) operand1->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ r_Minterval domain = ((QtMintervalData*)operand1)->getMintervalData();
+
+ RMDBGONCE( 4, RMDebug::module_qlparser, "QtMarrayOp", "Marray domain " << domain )
+
+ //
+ // add point data with its iterator name to the input list
+ //
+
+ // create a QtPointData object with corner point
+ QtPointData* point = new QtPointData( domain.get_origin() );
+ // set its iterator name
+ point->setIteratorName( iteratorName );
+ // if the list of binding variables is empty, create a new one and delete it afterwards
+ bool newInputList = false;
+ if( !inputList )
+ {
+ inputList = new QtDataList();
+ newInputList = true;
+ }
+ // add it to the list
+ inputList->push_back( point );
+
+ // determine types
+ BaseType* cellType = (BaseType*) input2->getDataStreamType().getType();
+ MDDBaseType* mddBaseType = (MDDBaseType*)dataStreamType.getType();
+
+ // create tile for result
+ Tile* resTile = new Tile( domain, cellType );
+
+ // create execution object QLArrayOp
+ QLMarrayOp* qlMarrayOp = new QLMarrayOp( input2, inputList, iteratorName, cellType );
+
+ try
+ {
+ // execute query engine marray operation
+ resTile->execMarrayOp( qlMarrayOp, domain, domain );
+ }
+ catch(...)
+ {
+ // free ressources
+ delete qlMarrayOp;
+ qlMarrayOp=NULL;
+ delete resTile;
+ resTile=NULL;
+
+ // remove point data object from inputList again
+ inputList->back()->deleteRef();
+ inputList->pop_back();
+ if( newInputList )
+ {
+ delete inputList;
+ inputList=NULL;
+ }
+
+ if( operand1 ) operand1->deleteRef();
+
+ throw;
+ }
+
+ // delete execution object again
+ delete qlMarrayOp;
+ qlMarrayOp=NULL;
+
+ // remove point data object from inputList again
+ inputList->back()->deleteRef();
+ inputList->pop_back();
+ if( newInputList )
+ {
+ delete inputList;
+ inputList=NULL;
+ }
+ // create MDDObj for result
+ MDDObj* mddres = new MDDObj( mddBaseType, domain );
+
+ // insert Tile in result mdd
+ mddres->insertTile( resTile );
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)mddres );
+
+ // delete old operands
+ if( operand1 ) operand1->deleteRef();
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtMarrayOp::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtMarrayOp Object " << getNodeType() << endl;
+
+ s << SPACE_STR(tab).c_str() << "Iterator Name: " << iteratorName.c_str() << endl;
+
+ QtBinaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtMarrayOp::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ s << iteratorName.c_str() << ",";
+
+ if( input1 )
+ input1->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ",";
+
+ if( input2 )
+ input2->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtTypeElement&
+QtMarrayOp::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtMarrayOp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input1 && input2 )
+ {
+
+ // check domain expression
+ const QtTypeElement& domainExp = input1->checkType( typeTuple );
+
+ if( domainExp.getDataType() != QT_MINTERVAL )
+ {
+ RMInit::logOut << "Error: QtMarrayOp::checkType() - Can not evaluate domain expression to an minterval." << endl;
+ parseInfo.setErrorNo(401);
+ throw parseInfo;
+ }
+
+ //
+ // check value expression
+ //
+
+ // add domain iterator to the list of bounded variables
+ bool newList = false;
+ if( !typeTuple )
+ {
+ typeTuple = new QtTypeTuple();
+ newList = true;
+ }
+ typeTuple->tuple.push_back( QtTypeElement( QT_POINT, iteratorName.c_str() ) );
+
+ // get type
+ const QtTypeElement& valueExp = input2->checkType( typeTuple );
+
+ // remove iterator again
+ typeTuple->tuple.pop_back();
+ if( newList )
+ {
+ delete typeTuple;
+ typeTuple = NULL;
+ }
+
+ // check type
+ if( valueExp.getDataType() != QT_BOOL && valueExp.getDataType() != QT_COMPLEX &&
+ valueExp.getDataType() != QT_CHAR && valueExp.getDataType() != QT_OCTET &&
+ valueExp.getDataType() != QT_USHORT && valueExp.getDataType() != QT_SHORT &&
+ valueExp.getDataType() != QT_ULONG && valueExp.getDataType() != QT_LONG &&
+ valueExp.getDataType() != QT_FLOAT && valueExp.getDataType() != QT_DOUBLE &&
+ valueExp.getDataType() != QT_COMPLEXTYPE1 && valueExp.getDataType() != QT_COMPLEXTYPE2 )
+ {
+ RMInit::logOut << "Error: QtMarrayOp::checkType() - Value expression must be either of type atomic or complex." << endl;
+ parseInfo.setErrorNo(412);
+ throw parseInfo;
+ }
+
+ // create MDD type
+ BaseType* cellType = (BaseType*)valueExp.getType();
+ MDDBaseType* mddBaseType = new MDDBaseType( "tmp", cellType );
+ TypeFactory::addTempType( mddBaseType );
+
+ dataStreamType.setType( mddBaseType );
+ }
+ else
+ RMInit::logOut << "Error: QtMarrayOp::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
diff --git a/qlparser/qtmarrayop.hh b/qlparser/qtmarrayop.hh
new file mode 100644
index 0000000..98b651c
--- /dev/null
+++ b/qlparser/qtmarrayop.hh
@@ -0,0 +1,90 @@
+#ifndef _QTMARRAYOP_
+#define _QTMARRAYOP_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtbinaryoperation.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the root of an marray expression.
+
+*/
+
+class QtMarrayOp : public QtBinaryOperation
+{
+ public:
+ /// constructor getting iterator, minterval expression, and cell expression
+ QtMarrayOp( const std::string& initIteratorName, QtOperation* mintervalExp, QtOperation* cellExp );
+
+ /// returns FALSE saying that the operation IS NOT commutative
+ virtual bool isCommutative() const;
+
+ /// optimizing load access
+ void optimizeLoad( QtTrimList* trimList );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+
+ /// attribute storing the iterator name
+ std::string iteratorName;
+};
+
+
+#include "qlparser/qtmarrayop.icc"
+
+#endif
+
diff --git a/qlparser/qtmarrayop.icc b/qlparser/qtmarrayop.icc
new file mode 100644
index 0000000..5acc69e
--- /dev/null
+++ b/qlparser/qtmarrayop.icc
@@ -0,0 +1,34 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtMarrayOp::getNodeType() const
+{
+ return nodeType;
+}
diff --git a/qlparser/qtmarrayop2.cc b/qlparser/qtmarrayop2.cc
new file mode 100644
index 0000000..4393486
--- /dev/null
+++ b/qlparser/qtmarrayop2.cc
@@ -0,0 +1,369 @@
+/*
+* 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, QtMarrayOp2: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtmarrayop2.cc,v 1.17 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtmarrayop2.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtpointdata.hh"
+#include "qlparser/qtmintervaldata.hh"
+#include "qlparser/qtmintervalop.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "qlparser/querytree.hh"
+
+#include "catalogmgr/typefactory.hh"
+#include "relcatalogif/basetype.hh"
+#include "relcatalogif/longtype.hh"
+
+#include "catalogmgr/algebraops.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+extern QueryTree* parseQueryTree;
+
+QtMarrayOp2::QtMarrayOp2( mddIntervalListType* & aList, QtOperation* & cellExp )
+: iterators( *aList ), qtOperation( cellExp ) {
+}
+
+QtMarrayOp2::~QtMarrayOp2(){
+}
+
+bool QtMarrayOp2::concatenateIntervals() {
+ QtData* data=NULL;
+ RMDBGENTER( 2, RMDebug::module_qlparser, "QtMarrayOp2", "Validity Check: " )
+
+ // check for validity
+ bool eflag=true;
+ mddIntervalListType::const_iterator ii;
+ QtNode::QtOperationList::const_iterator j;
+ QtNode::QtOperationList *ddd=NULL;
+ QtOperation *op1=NULL;
+ QtOperation *op2=NULL;
+
+ for (ii = iterators.begin(); ii != iterators.end() ; ii++) {
+ ddd = ((QtMintervalOp *)(ii->tree))->getInputs();
+ for (j = ddd->begin(); j != ddd->end(); j++) {
+ if((QtNode *)*j) {
+ if ((((QtNode *)*j)->getNodeType() == QtNode::QT_INTERVALOP))
+ {
+ op1 = ((QtBinaryOperation *)*j)->getInput1();
+ if (((QtNode *)op1)->getNodeType() != QtNode::QT_CONST) eflag=false;
+ op2 = ((QtBinaryOperation *)*j)->getInput2();
+ if (((QtNode *)op2)->getNodeType() != QtNode::QT_CONST) eflag=false;
+ } else
+ if (((QtNode *)*j)->getNodeType() != QtNode::QT_CONST)
+ eflag=false;
+ }
+ }
+ }
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "Validity check completed." )
+ if (eflag) {
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "eflag is true!" << endl )
+ // compute total dimension
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", endl << "QtMarrayOp2: Dimensions: " )
+ greatDimension=0;
+ mddIntervalListType::const_iterator i;
+ for (i = iterators.begin(); i != iterators.end() ; i++) {
+ // evaluate intervals
+ data = (i->tree)->evaluate(0);
+ r_Dimension dimension = ((QtMintervalData*)data)->getMintervalData().dimension();
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", dimension << " | " );
+ greatDimension += dimension;
+ }
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", " Total " << greatDimension << endl )
+
+ // concatenate the data of the intervals into one big interval
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "QtMarray2: Domains: " )
+ greatDomain = r_Minterval( greatDimension );
+ for (i = iterators.begin(); i != iterators.end() ; i++) {
+ // evaluate intervals
+ data = i->tree->evaluate(0);
+ r_Minterval domain = ((QtMintervalData*)data)->getMintervalData();
+ r_Dimension dimension = domain.dimension();
+ r_Dimension jj;
+ for (jj=0; jj != dimension; jj++) {
+ r_Sinterval part = domain[jj];
+ greatDomain << part;
+ }
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", domain << " | " )
+ }
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", " Total: " << greatDomain << endl )
+
+ // concatenate the identifier names to one big identifier name
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "QtMarray2: Iterators: " )
+ greatIterator = string("");
+ string iname("");
+ for (i = iterators.begin(); i != iterators.end() ; i++) {
+ // get iterator name
+ iname = string(i->variable);
+ greatIterator = greatIterator + string(" ") + string(i->variable);
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", i->variable << " | " )
+ }
+ RMDBGEXIT( 2, RMDebug::module_qlparser, "QtMarrayOp2", " Total: " << greatIterator << endl )
+ } else
+ RMDBGEXIT( 2, RMDebug::module_qlparser, "QtMarrayOp2", " eflag is false! " << greatIterator << endl )
+ return eflag;
+}
+
+
+
+void QtMarrayOp2::rewriteVars( ) {
+ if (!oldMarray) {
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "concatenateIteratorNames: " )
+ mddIntervalListType::const_iterator i;
+ // concatenate the identifier names to one big identifier name
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "QtMarray2: Iterators: " )
+ greatIterator = string("");
+ string iname("");
+ for (i = iterators.begin(); i != iterators.end() ; i++) {
+ // get iterator name
+ iname = string(i->variable);
+ greatIterator = greatIterator + string(" ") + string(i->variable);
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", i->variable << " | " )
+ }
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", " Total: " << greatIterator << endl )
+ }
+ traverse(qtOperation);
+}
+
+void QtMarrayOp2::traverse(QtOperation *&node) {
+
+ if (node != 0)
+ {
+ QtOperation* temp = NULL;
+
+
+ if (((QtNode *)node)->getNodeType() == QtNode::QT_DOMAIN_OPERATION)
+ {
+ // syntax: dinput [ dmiop ]
+
+ // traverse dmiop
+ QtOperation *dmiop = ((QtDomainOperation *)node)->getMintervalOp();
+ temp = (QtOperation*)dmiop;
+ traverse(temp);
+ dmiop = temp;
+ ((QtDomainOperation *)node)->setMintervalOp(dmiop);
+
+ // if dinput == QtVariable then rewrite it
+ QtOperation *dinput = ((QtDomainOperation *)node)->getInput();
+
+ // if not a variable, then recurse
+ if (((QtNode *)dinput)->getNodeType() != QtNode::QT_MDD_VAR)
+ {
+ // traverse dinput
+ temp = (QtOperation *)dinput;
+ traverse(temp);
+ dinput = temp;
+ ((QtDomainOperation *)node)->setInput(dinput);
+
+ // get childs and traverse them
+ QtNode::QtNodeList* childList = node->getChilds(QtNode::QT_DIRECT_CHILDS);
+ for( QtNode::QtNodeList::iterator iter = childList->begin(); iter != childList->end(); iter++ )
+ {
+ temp = (QtOperation*)*iter;
+ traverse(temp);
+ *iter = temp;
+ };
+ delete childList;
+ childList=NULL;
+ };
+ } else
+ {
+
+ if (node->getNodeType() == QtNode::QT_MDD_VAR) {
+ if (QueryTree::symtab.lookupSymbol(((QtVariable *)node)->getIteratorName()))
+ {
+ if (!oldMarray)
+ {
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", endl << "marray2 var identifier:" << ((QtVariable *)node)->getIteratorName() << " replacing with " << greatIterator << endl )
+ ((QtVariable *)node)->setIteratorName(greatIterator);
+ };
+ // replace with var[0]
+ QtDomainOperation *dop = new QtDomainOperation( new QtConst (new QtAtomicData((r_Long)0, sizeof(r_Long))) /*new QtPointOp( lop )*/ );
+ dop->setInput( (QtVariable *)node );
+ node = dop;
+ parseQueryTree->addDomainObject( dop );
+ };
+ } else
+ {
+
+ // traverse inputs
+ switch (((QtNode *)node)->getNodeType()) {
+/*
+ // with no input
+ case QtNode::QT_UNDEFINED_NODE:
+ case QtNode::QT_MDD_ACCESS:
+ case QtNode::QT_OPERATION_ITERATOR:
+ case QtNode::QT_SELECTION_ITERATOR:
+ case QtNode::QT_JOIN_ITERATOR:
+ case QtNode::QT_UPDATE:
+ case QtNode::QT_INSERT:
+ case QtNode::QT_DELETE:
+ case QtNode::QT_COMMAND:
+ case QtNode::QT_PYRAMID:
+ case QtNode::QT_MDD_VAR:
+ case QtNode::QT_UDFCALLOP:
+ case QtNode::QT_CONST:
+ case QtNode::QT_MDD_STREAM:
+*/
+ // from Unary
+ case QtNode::QT_TANH:
+ case QtNode::QT_TAN:
+ case QtNode::QT_SQRT:
+ case QtNode::QT_SINH:
+ case QtNode::QT_SIN:
+ case QtNode::QT_NOT:
+ case QtNode::QT_LOG:
+ case QtNode::QT_LN:
+ case QtNode::QT_EXP:
+ case QtNode::QT_DOT:
+ case QtNode::QT_COSH:
+ case QtNode::QT_COS:
+ case QtNode::QT_ARCTAN:
+ case QtNode::QT_ARCSIN:
+ case QtNode::QT_ARCCOS:
+ case QtNode::QT_ABS:
+ case QtNode::QT_REALPART:
+ case QtNode::QT_IMAGINARPART:
+ case QtNode::QT_CAST:
+ case QtNode::QT_SDOM:
+ case QtNode::QT_OID:
+ case QtNode::QT_LO:
+ case QtNode::QT_HI:
+// case QtNode::QT_DOMAIN_OPERATION:
+ case QtNode::QT_CONVERSION:
+ case QtNode::QT_SOME:
+ case QtNode::QT_MINCELLS:
+ case QtNode::QT_MAXCELLS:
+ case QtNode::QT_COUNTCELLS:
+ case QtNode::QT_AVGCELLS:
+ case QtNode::QT_ALL:
+ case QtNode::QT_ADDCELLS:
+ case QtNode::QT_CSE_ROOT:
+ {
+ QtOperation *uinput = ((QtUnaryOperation *)node)->getInput();
+
+ temp = (QtOperation *)uinput;
+ traverse(temp);
+ uinput = temp;
+
+ ((QtUnaryOperation *)node)->setInput(uinput);
+ };
+ break;
+
+ // from Binary
+ case QtNode::QT_SHIFT:
+ case QtNode::QT_SCALE:
+ case QtNode::QT_MARRAYOP:
+ case QtNode::QT_INTERVALOP:
+ case QtNode::QT_CONDENSEOP:
+ case QtNode::QT_XOR:
+ case QtNode::QT_PLUS:
+ case QtNode::QT_OR:
+ case QtNode::QT_NOT_EQUAL:
+ case QtNode::QT_MULT:
+ case QtNode::QT_MINUS:
+ case QtNode::QT_LESS_EQUAL:
+ case QtNode::QT_LESS:
+ case QtNode::QT_IS:
+ case QtNode::QT_EQUAL:
+ case QtNode::QT_DIV:
+ case QtNode::QT_AND:
+ case QtNode::QT_OVERLAY:
+ case QtNode::QT_BIT:
+ {
+ QtOperation *binput1 = ((QtBinaryOperation *)node)->getInput1();
+ QtOperation *binput2 = ((QtBinaryOperation *)node)->getInput2();
+
+ QtOperation* temp1 = 0;
+ QtOperation* temp2 = 0;
+ temp1 = (QtOperation *)binput1;
+ temp2 = (QtOperation *)binput2;
+ traverse(temp1);
+ traverse(temp2);
+ binput1 = temp1;
+ binput2 = temp2;
+
+ ((QtBinaryOperation *)node)->setInput1(binput1);
+ ((QtBinaryOperation *)node)->setInput2(binput2);
+ };
+ break;
+
+ // from Nary
+ case QtNode::QT_POINTOP:
+ case QtNode::QT_MINTERVALOP:
+ {
+ QtNode::QtOperationList *ninput = ((QtNaryOperation *)node)->getInputs();
+
+ for( QtNode::QtOperationList::iterator iter = ninput->begin(); iter != ninput->end(); iter++ )
+ {
+ temp = (QtOperation *)*iter;
+ traverse(temp);
+ *iter = temp;
+ };
+
+ ((QtNaryOperation *)node)->setInputs(ninput);
+ };
+ break;
+ default: {
+ // do nothing
+ }; break;
+ };
+
+ // get childs and traverse them
+ QtNode::QtNodeList* childList = node->getChilds(QtNode::QT_DIRECT_CHILDS);
+ for( QtNode::QtNodeList::iterator iter = childList->begin(); iter != childList->end(); iter++ )
+ {
+ temp = (QtOperation*)*iter;
+ traverse(temp);
+ *iter = temp;
+ };
+ delete childList;
+ childList=NULL;
+ };
+ };
+ };
+}
+
+
+
+
diff --git a/qlparser/qtmarrayop2.hh b/qlparser/qtmarrayop2.hh
new file mode 100644
index 0000000..94e67e6
--- /dev/null
+++ b/qlparser/qtmarrayop2.hh
@@ -0,0 +1,113 @@
+#ifndef _QTMARRAYOP2_
+#define _QTMARRAYOP2_
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the root of a fake marray expression.
+
+*/
+
+#include "raslib/minterval.hh"
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include <vector>
+#include "qlparser/qtoperation.hh"
+#include "qlparser/qtdomainoperation.hh"
+#include "qlparser/qtvariable.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtpointop.hh"
+#include "qlparser/qtconst.hh"
+
+class QtMarrayOp2 {
+ public:
+ /// variables to pass to old marray
+ r_Dimension greatDimension;
+ r_Minterval greatDomain;
+ std::string greatIterator;
+
+ /// pair (Identifier, Interval)
+ typedef struct {
+ std::string variable;
+ QtOperation* tree;
+ ParseInfo parseInfo;
+ } mddIntervalType;
+
+ /// list storing pairs (Identifier, Interval)
+ typedef vector<mddIntervalType> mddIntervalListType;
+
+ /// constructor getting iterator, minterval expression, and cell expression
+ QtMarrayOp2( mddIntervalListType* & aList, QtOperation* & cellExp );
+
+ /// destructor
+ virtual ~QtMarrayOp2();
+
+ /// optimizing load access
+ virtual bool concatenateIntervals();
+ virtual void rewriteVars();
+ inline QtOperation *getInput() const;
+ ///
+ inline const ParseInfo& getParseInfo();
+ ///
+ inline void setParseInfo( const ParseInfo &info );
+ ///
+ inline void setOldMarray( bool value );
+
+ protected:
+ /// attribute for parser info
+ ParseInfo parseInfo;
+
+ private:
+ /// attribute storing the iterators
+ mddIntervalListType iterators;
+
+ /// attribute storing the cellExp
+ QtOperation *qtOperation;
+
+ /// tree traversal
+ virtual void traverse(QtOperation *&node);
+
+ /// replace Iterator name if this is false
+ bool oldMarray;
+
+};
+
+#include "qlparser/qtmarrayop2.icc"
+
+#endif
+
diff --git a/qlparser/qtmarrayop2.icc b/qlparser/qtmarrayop2.icc
new file mode 100644
index 0000000..8155712
--- /dev/null
+++ b/qlparser/qtmarrayop2.icc
@@ -0,0 +1,54 @@
+/*
+* 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:
+ *
+ ************************************************************/
+
+inline QtOperation *QtMarrayOp2::getInput() const
+{
+ return qtOperation;
+}
+
+inline const ParseInfo&
+QtMarrayOp2::getParseInfo()
+{
+ return parseInfo;
+}
+
+inline void
+QtMarrayOp2::setParseInfo( const ParseInfo &info )
+{
+ parseInfo = info;
+}
+
+inline void
+QtMarrayOp2::setOldMarray( bool value )
+{
+ oldMarray = value;
+};
diff --git a/qlparser/qtmdd.cc b/qlparser/qtmdd.cc
new file mode 100644
index 0000000..b3e994f
--- /dev/null
+++ b/qlparser/qtmdd.cc
@@ -0,0 +1,329 @@
+#include "mymalloc/mymalloc.h"
+/*
+* 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, QtMDD: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtmdd.cc,v 1.44 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtscalardata.hh"
+#include "qlparser/qtmintervaldata.hh"
+#include "qlparser/qtoperation.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "tilemgr/tile.hh"
+#include "mddmgr/mddcoll.hh"
+#include "catalogmgr/typefactory.hh"
+
+#include "raslib/rmdebug.hh"
+
+#include "relcatalogif/mdddimensiontype.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+#include <iostream>
+
+extern MDDColl* mddConstants;
+
+QtMDD::QtMDD( MDDObj* ptr )
+ : QtData(),
+ mddObject( ptr )
+{
+ if( ptr && ptr->isPersistent() )
+ setLifetime( QtData::QT_PERSISTENT );
+ else
+ setLifetime( QtData::QT_TRANSIENT );
+
+ if( ptr )
+ loadDomain = ptr->getDefinitionDomain();
+}
+
+
+QtMDD::QtMDD( MDDObj* ptr, string name )
+ : QtData( name ),
+ mddObject( ptr )
+{
+ if( ptr && ptr->isPersistent() )
+ setLifetime( QtData::QT_PERSISTENT );
+ else
+ setLifetime( QtData::QT_TRANSIENT );
+
+ if( ptr )
+ loadDomain = ptr->getCurrentDomain();
+}
+
+
+QtMDD::QtMDD( QtOperation* mintervalOp, list<QtScalarData*>* literalList )
+ : QtData(), mddObject(0)
+{
+ list< QtScalarData* >::iterator elemIter;
+ QtScalarData* scalarElem=NULL;
+
+ //
+ // evaluate domain
+ //
+
+ if( mintervalOp )
+ {
+
+ QtData* operand = mintervalOp->evaluate(NULL);
+
+ if( operand->getDataType() != QT_MINTERVAL )
+ {
+ RMInit::logOut << "Error: QtMDD( QtOperation*, list<QtScalarData*>* ) - Can not evaluate domain expression to an minterval." << endl;
+ ParseInfo errorInfo = getParseInfo();
+ errorInfo.setErrorNo(401);
+ throw errorInfo;
+ }
+
+ r_Minterval domain = ((QtMintervalData*)operand)->getMintervalData();
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ //
+ // determine base type
+ //
+
+ if( literalList->size()!=0 )
+ {
+ scalarElem = *(literalList->begin());
+ const BaseType* baseType = scalarElem->getValueType();
+
+ //
+ // allocate memory and fill it with cell values of the list
+ //
+ unsigned long cellCount = 0;
+ unsigned long cellSize = baseType->getSize();
+ char* cellBuffer = (char*)mymalloc( domain.cell_count()*cellSize );
+ char* bufferOffset = cellBuffer;
+
+ for( elemIter = literalList->begin(); elemIter != literalList->end(); elemIter++ )
+ {
+ scalarElem = *elemIter;
+ cellCount++;
+
+ // do not write beyond array boundary
+ if( cellCount <= domain.cell_count() )
+ {
+ if( scalarElem->getValueType() != baseType )
+ {
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtMDD", "Error: QtMDD() - All cell values of an MDD must be of the same type." )
+ free( cellBuffer );
+ cellBuffer=NULL;
+ ParseInfo errorInfo = getParseInfo();
+ errorInfo.setErrorNo(301);
+ throw errorInfo;
+ }
+ memcpy( (void*)bufferOffset, (void*)(scalarElem->getValueBuffer()), (unsigned int)cellSize );
+ bufferOffset += cellSize;
+ }
+ }
+
+ // delete literal list - done by caller
+ // delete literalList;
+
+ if( cellCount != domain.cell_count() )
+ {
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtMDD", "Error: QtMDD() - Number of cells specified does not match the number of cells of the given spatial domain." )
+ free( cellBuffer );
+ cellBuffer=NULL;
+ ParseInfo errorInfo = getParseInfo();
+ errorInfo.setErrorNo(302);
+ throw errorInfo;
+ }
+
+ //
+ // create transient tile
+ //
+ Tile* tile = new Tile( domain, baseType, cellBuffer, 0 );
+
+ //
+ // create transiend mddObject and attach created tile
+ //
+ MDDDimensionType* mddDimensionType = new MDDDimensionType( "tmp", baseType, domain.dimension() );
+ TypeFactory::addTempType( mddDimensionType );
+ mddObject = new MDDObj( mddDimensionType, domain );
+ mddObject->insertTile( tile );
+ loadDomain = domain;
+ }
+ else
+ RMInit::logOut << "Internal Error: QtMDD( domain, literalList ) - list of literal lists is empty" << endl;
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtMDD( QtOperation*, list<QtScalarData*>* ) - Domain of MDD constructor has to be defined." << endl;
+ ParseInfo errorInfo = getParseInfo();
+ errorInfo.setErrorNo(400);
+ throw errorInfo;
+ }
+
+}
+
+
+
+QtMDD::QtMDD( int constantNo )
+ : QtData(),
+ mddObject( NULL )
+{
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtMDD", "QtMDD() - constant no " << constantNo )
+
+ if( mddConstants )
+ {
+
+ MDDCollIter* mddIter = mddConstants->createIterator();
+ //for( mddIter->reset(); mddIter->notDone(); mddIter->advance() )
+ mddIter->reset();
+
+ // take the MDD object
+ mddObject = mddIter->getElement();
+
+ // remove it from the constant list
+ mddConstants->remove( mddObject );
+
+ delete mddIter;
+ mddIter = NULL;
+
+ if( mddObject )
+ loadDomain = mddObject->getCurrentDomain();
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtMDD() - Unsatisfied MDD constant parameter." << endl;
+ ParseInfo errorInfo = getParseInfo();
+ errorInfo.setErrorNo(373);
+ throw errorInfo;
+ }
+
+}
+
+
+
+QtMDD::QtMDD( const QtMDD& obj )
+ : QtData( obj ),
+ mddObject( obj.mddObject )
+{
+}
+
+
+QtMDD::~QtMDD()
+{
+ //this causes problems when passing more than one trans mddobj
+ if( mddObject && getLifetime() == QtData::QT_TRANSIENT )
+ {
+ RMDBGONCE( 2, RMDebug::module_qlparser, "QtMDD", "~QtMDD() - transient MDD object " << mddObject << " deleted" )
+ delete mddObject;
+ mddObject = NULL;
+ }
+}
+
+
+BaseType*
+QtMDD::getCellType() const
+{
+ return (BaseType*)mddObject->getCellType();
+}
+
+
+
+unsigned long
+QtMDD::getCellSize() const
+{
+ return mddObject->getCellType()->getSize();
+}
+
+
+
+QtDataType
+QtMDD::getDataType() const
+{
+ return QT_MDD;
+}
+
+
+
+bool
+QtMDD::equal( const QtData* /*obj*/ ) const
+{
+ int returnValue = false; // not equal by initialization
+
+ // Later on, MDD constants can be compared.
+
+ return returnValue;
+}
+
+
+
+string
+QtMDD::getSpelling() const
+{
+ string result;
+
+ // no spelling right now
+
+ return result;
+}
+
+
+
+char* QtMDD::getTypeStructure() const
+{
+ if( mddObject )
+ return mddObject->getMDDBaseType()->getTypeStructure();
+ else
+ return NULL;
+}
+
+
+
+void
+QtMDD::printStatus( ostream& stream ) const
+{
+ if( mddObject )
+ stream << "MDD object: load domain: " << loadDomain << endl;
+ else
+ stream << "<no object>" << endl;
+
+ QtData::printStatus( stream );
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtMDD", mddObject->printStatus(0, stream); )
+
+RMDBGIF(30, RMDebug::module_qlparser, "QtMDD", \
+ vector<Tile*>* vec = mddObject->getTiles(); \
+ for( int i = 0; i<vec->size(); i++ ) \
+ ((*vec)[i])->printStatus(); \
+ delete vec; vec=NULL; )
+}
diff --git a/qlparser/qtmdd.hh b/qlparser/qtmdd.hh
new file mode 100644
index 0000000..bbbe195
--- /dev/null
+++ b/qlparser/qtmdd.hh
@@ -0,0 +1,138 @@
+#ifndef _QTMDD_
+#define _QTMDD_
+
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtscalardata.hh"
+#include "catalogmgr/typefactory.hh"
+#include "raslib/minterval.hh"
+
+#include <string>
+#include <list>
+
+// forward declarations
+class MDDObj;
+class QtOperation;
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class encapsulates a pointer to an object of type {\tt MDDObj}.
+ Its purpose is to have the {\tt MDDObj} object available as a descendant
+ of class {\tt QtData}. The class does not care of the memory management
+ of the {\tt MDDObj} object.
+
+ Note: The attribute lifetime of the superclass QtData ist set implicit
+ in the constructor functions!
+*/
+
+class QtMDD : public QtData
+{
+ public:
+ // list of lists of \Ref{QtScalarData} objects
+ // typedef list< list<QtScalarData*>* > QtDimensionList;
+
+ /// constructor getting the pointer to the MDDObj object
+ QtMDD( MDDObj* ptr );
+
+ /// constructor getting the pointer to the MDDObj object and an iterator name
+ QtMDD( MDDObj* ptr, std::string name );
+
+ /// constructor getting a domain expression and a literal list for initializing a transient constant object
+ QtMDD( QtOperation* mintervalOp, std::list<QtScalarData*>* literalList );
+ /**
+ The list of literal objects is not deleted.
+ */
+
+ /// constructor getting the number of an mdd constant
+ QtMDD( int constantNo );
+
+ /// copy constructor
+ QtMDD( const QtMDD& obj );
+
+ /// destructor
+ virtual ~QtMDD();
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ /// gets the pointer to the MDDObj object
+ inline MDDObj* getMDDObject() const;
+ /// sets the pointer to the MDDObj object and it does not care about the old pointer
+ inline void setMDDObject( MDDObj* ptr );
+ /// read method for loadDomain
+ inline const r_Minterval& getLoadDomain() const;
+ /// write method for loadDomain
+ inline void setLoadDomain( r_Minterval& newLoadDomain );
+
+ /// returns a null-terminated string describing the type structure
+ virtual char* getTypeStructure() const;
+ /**
+ The string pointer has to be free using free() by the caller.
+ */
+ ///
+ ///
+ //@}
+
+ /// returns a pointer to the cell type
+ BaseType* getCellType() const;
+
+ /// returns size of one cell in bytes
+ unsigned long getCellSize() const;
+
+ /// returns {\tt QT_MDD}
+ virtual QtDataType getDataType() const;
+
+ /// compares data content
+ virtual bool equal( const QtData* obj ) const;
+
+ /// returns content dependent string representation
+ virtual std::string getSpelling() const;
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+
+ private:
+ /// prevents from using the default constructor
+ QtMDD(){};
+
+ /// pointer to the MDDObj object
+ MDDObj* mddObject;
+
+ /// load domain
+ r_Minterval loadDomain;
+};
+
+#include "qlparser/qtmdd.icc"
+
+#endif
+
diff --git a/qlparser/qtmdd.icc b/qlparser/qtmdd.icc
new file mode 100644
index 0000000..8fee948
--- /dev/null
+++ b/qlparser/qtmdd.icc
@@ -0,0 +1,59 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline MDDObj*
+QtMDD::getMDDObject() const
+{
+ return mddObject;
+}
+
+
+inline void
+QtMDD::setMDDObject( MDDObj* ptr )
+{
+ mddObject = ptr;
+}
+
+
+
+inline const r_Minterval&
+QtMDD::getLoadDomain() const
+{
+ return loadDomain;
+}
+
+
+inline void
+QtMDD::setLoadDomain( r_Minterval& newLoadDomain )
+{
+ loadDomain = newLoadDomain;
+}
+
+
diff --git a/qlparser/qtmddaccess.cc b/qlparser/qtmddaccess.cc
new file mode 100644
index 0000000..db009e3
--- /dev/null
+++ b/qlparser/qtmddaccess.cc
@@ -0,0 +1,250 @@
+/*
+* 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, QtMDDAccess: $Id: qtmddaccess.cc,v 1.30 2002/04/23 16:22:41 purify Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtmddaccess.hh"
+#include "qlparser/qtmdd.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+#include "mddmgr/mddcoll.hh"
+#include "mddmgr/mddcolliter.hh"
+
+#include "servercomm/servercomm.hh"
+
+extern ServerComm::ClientTblElt* currentClientTblElt;
+
+const QtNode::QtNodeType QtMDDAccess::nodeType = QT_MDD_ACCESS;
+
+QtMDDAccess::QtMDDAccess( const string& collectionNameNew )
+ : QtONCStream(),
+ collectionName( collectionNameNew ),
+ mddColl(NULL),
+ mddIter(NULL)
+{
+}
+
+
+QtMDDAccess::QtMDDAccess( const string& collectionNameNew, const string& initName )
+ : QtONCStream(),
+ collectionName( collectionNameNew ),
+ iteratorName( initName ),
+ mddColl(NULL),
+ mddIter(NULL)
+{
+}
+
+
+QtMDDAccess::~QtMDDAccess()
+{
+ //just to be on the safe side
+ close();
+}
+
+
+void
+QtMDDAccess::open()
+{
+ RMDBCLASS( "QtMDDAccess", "open()", "qlparser", __FILE__, __LINE__ )
+
+ // delete an existing iterator
+ if( mddIter )
+ {
+ delete mddIter;
+ mddIter=NULL;
+ }
+
+ // create the iterator
+ mddIter = mddColl->createIterator();
+
+ //for( mddIter->reset(); mddIter->notDone(); mddIter->advance() )
+ // mddIter->getElement()->printStatus();
+
+ mddIter->reset();
+}
+
+
+QtNode::QtDataList*
+QtMDDAccess::next()
+{
+ RMDBCLASS( "QtMDDAccess", "next()", "qlparser", __FILE__, __LINE__ )
+
+ QtDataList* returnValue = NULL;
+ MDDObj* ptr = NULL;
+
+ if( mddColl && mddIter && mddIter->notDone() )
+ {
+ //
+ // create a list with a pointer to the next element of the mdd collection
+ //
+
+ // encapsulate the next MDDObj in an QtMDD object
+ ptr = mddIter->getElement();
+ QtMDD* elem = new QtMDD( ptr, iteratorName );
+
+
+
+ // create the list
+ QtNode::QtDataList* dataList = new QtNode::QtDataList(1); // create container to contain one element
+
+ // insert the element into the list
+ (*dataList)[0] = elem;
+
+ // if mddColl is not persistent delete thist from
+ // collection to avoid multiple destruction
+ if(!mddColl->isPersistent()) {
+ mddColl->remove(ptr);
+ mddIter->reset();
+ }
+ else {
+ // increment the iterator
+ mddIter->advance();
+ }
+
+ returnValue = dataList;
+ }
+
+ return returnValue;
+}
+
+
+void
+QtMDDAccess::close()
+{
+ RMDBCLASS( "QtMDDAccess", "close()", "qlparser", __FILE__, __LINE__ )
+
+ // delete the mdd iterator
+ if( mddIter )
+ {
+ delete mddIter;
+ mddIter=NULL;
+ }
+
+ // This is now done in ServerComm::ClientTblElt::releaseTransferStructures().
+ //
+ // delete the mdd objects and the mdd collection
+ // if( mddColl )
+ // {
+ // mddColl->releaseAll();
+ // delete mddColl;
+ // }
+}
+
+
+void
+QtMDDAccess::reset()
+{
+ if( mddIter ) mddIter->reset();
+}
+
+
+void
+QtMDDAccess::printTree( int tab, ostream& s, QtChildType /*mode*/ )
+{
+ s << SPACE_STR(tab).c_str() << "QtMDDAccess Object: type " << flush;
+ dataStreamType.printStatus( s );
+ s << endl;
+
+ s << SPACE_STR(tab).c_str() << collectionName.c_str()
+ << " <- " << iteratorName.c_str() << endl;
+}
+
+
+
+void
+QtMDDAccess::printAlgebraicExpression( ostream& s )
+{
+ s << collectionName.c_str() << " as " << iteratorName.c_str() << flush;
+}
+
+
+
+const QtTypeTuple&
+QtMDDAccess::checkType()
+{
+ RMDBCLASS( "QtMDDAccess", "checkType()", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType = QtTypeTuple(0);
+
+ //
+ // create the collection and add it to the list in the client table entry
+ //
+
+ try
+ {
+ mddColl = MDDColl::getMDDCollection( collectionName.c_str() );
+
+ if( currentClientTblElt )
+ {
+ if (mddColl->isPersistent())
+ {
+ if( !(currentClientTblElt->persMDDCollections) )
+ currentClientTblElt->persMDDCollections = new vector<MDDColl*>();
+
+ currentClientTblElt->persMDDCollections->push_back( (MDDColl*)mddColl );
+ }
+ else {
+ currentClientTblElt->transferColl = mddColl;
+ }
+ }
+ else {
+ RMInit::logOut << "Internal Error in QtMDDAccess::open(): No client context available" << endl;
+ }
+ }
+ catch(...)
+ {
+ RMInit::logOut << "Error: QtMDDAccess::open() collection: " << collectionName.c_str() << " is unknown" << endl;
+ parseInfo.setErrorNo(355);
+ throw parseInfo;
+ }
+
+ CollectionType* collType = (CollectionType*) mddColl->getCollectionType();
+
+ if( !collType )
+ RMInit::logOut << "Internal error in QtMDDAccess::checkType() - no collection type available" << endl;
+
+ dataStreamType = QtTypeTuple( 1 );
+
+ dataStreamType.tuple[0].setType( collType->getMDDType() );
+ dataStreamType.tuple[0].setName( iteratorName.c_str() );
+
+ return dataStreamType;
+}
diff --git a/qlparser/qtmddaccess.hh b/qlparser/qtmddaccess.hh
new file mode 100644
index 0000000..433f805
--- /dev/null
+++ b/qlparser/qtmddaccess.hh
@@ -0,0 +1,114 @@
+#ifndef _QTMDDACCESS_
+#define _QTMDDACCESS_
+
+#include "qlparser/qtoncstream.hh"
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+// forward declarations
+class MDDColl;
+class MDDCollIter;
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+This class encapsulates a MDDCollection. It gives access to the elements
+through the ONC protocol. The list returned by next() consists of just one
+element.
+
+*/
+
+class QtMDDAccess : public QtONCStream
+{
+ public:
+ /// constructor getting the collection name if no iterator name is specified
+ QtMDDAccess( const std::string& collectionName );
+
+ /// constructor getting collection and iterator name
+ QtMDDAccess( const std::string& collectionName, const std::string& iteratorName );
+
+ /// destructor
+ virtual ~QtMDDAccess();
+
+ //@Man: Operations of the ONC protocol
+ //@{
+ ///
+ void open();
+ ///
+ QtDataList* next();
+ ///
+ void close();
+ ///
+ void reset();
+ //@}
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method for retrieving the current MDD collection
+ inline MDDColl* getMDDColl();
+
+ /// type checking
+ virtual const QtTypeTuple& checkType();
+
+ private:
+ /// name of the MDD collection
+ std::string collectionName;
+
+ /// name of the iterator
+ std::string iteratorName;
+
+ /// pointer to the MDD collection
+ MDDColl* mddColl;
+
+ /// pointer to the curent iterator
+ MDDCollIter* mddIter;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtmddaccess.icc"
+
+#endif
+
diff --git a/qlparser/qtmddaccess.icc b/qlparser/qtmddaccess.icc
new file mode 100644
index 0000000..37a8e3b
--- /dev/null
+++ b/qlparser/qtmddaccess.icc
@@ -0,0 +1,42 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtMDDAccess::getNodeType() const
+{
+ return nodeType;
+}
+
+
+
+inline MDDColl*
+QtMDDAccess:: getMDDColl()
+{
+ return mddColl;
+}
diff --git a/qlparser/qtmintervaldata.cc b/qlparser/qtmintervaldata.cc
new file mode 100644
index 0000000..da5343d
--- /dev/null
+++ b/qlparser/qtmintervaldata.cc
@@ -0,0 +1,188 @@
+/*
+* 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, QtMintervalData: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtmintervaldata.cc,v 1.10 2005/09/03 20:17:55 rasdev Exp $";
+
+using namespace std;
+
+using namespace std;
+
+#include "qlparser/qtmintervaldata.hh"
+
+#include <iostream>
+#include <cstring>
+
+QtMintervalData::QtMintervalData( const r_Minterval& minterval, vector<bool>* initTrimFlags )
+ : mintervalData(minterval), QtData(), trimFlags( initTrimFlags )
+{
+ if( !trimFlags )
+ {
+ trimFlags = new vector<bool>( minterval.dimension() );
+
+ for( int i=0; i<trimFlags->size(); i++ )
+ (*trimFlags)[i] = true;
+ }
+}
+
+
+
+QtMintervalData::~QtMintervalData()
+{
+ if( trimFlags ) {delete trimFlags; trimFlags=NULL; }
+}
+
+
+
+QtDataType
+QtMintervalData::getDataType() const
+{
+ return QT_MINTERVAL;
+}
+
+
+
+bool
+QtMintervalData::equal( const QtData* obj ) const
+{
+ bool returnValue = false; // not equal by initialization
+
+ if( obj->getDataType() == QT_MINTERVAL )
+ {
+ QtMintervalData* mint = (QtMintervalData*)obj;
+
+ // 1. check domains
+ returnValue = (mintervalData == mint->getMintervalData());
+
+ // 2. check projection flags !!!
+ if( returnValue && trimFlags && mint->getTrimFlags() )
+ for( int i=0; i<mintervalData.dimension(); i++ )
+ if (!((*trimFlags)[i] == (*(mint->getTrimFlags()))[i]))
+ {
+ returnValue = false;
+ break;
+ }
+ }
+
+ return returnValue;
+}
+
+
+
+std::string
+QtMintervalData::getSpelling() const
+{
+ std::string result;
+
+ // buffer
+ int bufferLen = mintervalData.dimension() * 50; // on the save side for two integers per dimension plus colon and brackets
+ char* buffer = new char[ bufferLen ];
+ // replaced deprecated ostrstream -- PB 2005-jan-14
+ // ostrstream bufferStream( buffer, bufferLen );
+ ostringstream bufferStream( buffer );
+
+ if( trimFlags )
+ {
+ bufferStream << "[" << std::flush;
+ for( int i=0; i<mintervalData.dimension(); i++ )
+ {
+ if( i > 0 ) bufferStream << "'" << std::flush;
+
+ if( (*trimFlags)[i] )
+ bufferStream << mintervalData[i] << std::flush;
+ else
+ bufferStream << mintervalData[i].low() << std::flush;
+ }
+ bufferStream << "]" << std::ends;
+ }
+ else
+ bufferStream << mintervalData << std::ends;
+
+ result.append( std::string( buffer ) );
+
+ delete[] buffer;
+ buffer = NULL;
+
+ return result;
+}
+
+
+
+char* QtMintervalData::getTypeStructure() const
+{
+ return strdup("minterval");
+}
+
+
+
+void
+QtMintervalData::printStatus( std::ostream& stream ) const
+{
+ stream << "minterval, value: " << std::flush;
+
+ if( trimFlags )
+ {
+ stream << "[" << std::flush;
+ for( int i=0; i<mintervalData.dimension(); i++ )
+ {
+ if( i > 0 ) stream << "," << std::flush;
+
+ if( (*trimFlags)[i] )
+ stream << mintervalData[i] << std::flush;
+ else
+ stream << mintervalData[i].low() << std::flush;
+ }
+ stream << "]" << std::flush;
+ }
+ else
+ stream << mintervalData << std::flush;
+
+ QtData::printStatus( stream );
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtmintervaldata.hh b/qlparser/qtmintervaldata.hh
new file mode 100644
index 0000000..9fcd705
--- /dev/null
+++ b/qlparser/qtmintervaldata.hh
@@ -0,0 +1,108 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#ifndef _QTMINTERVALDATA_
+#define _QTMINTERVALDATA_
+
+#include "qlparser/qtdata.hh"
+
+#include "raslib/minterval.hh"
+#include "raslib/point.hh"
+
+#include <string>
+#include <vector>
+#include <iostream>
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+ The class encapsulates an minterval.
+*/
+
+class QtMintervalData : public QtData
+{
+ public:
+ /// constructor getting the minterval
+ QtMintervalData( const r_Minterval& minterval, vector<bool>* initTrimFlags = NULL );
+
+ /// virtual destructor
+ virtual ~QtMintervalData();
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+
+ ///
+ inline const r_Minterval& getMintervalData() const;
+ ///
+ inline void setMintervalData( const r_Minterval& interval );
+ //
+ // inline void setMintervalData( const r_Point& point );
+ ///
+ inline const vector<bool>* getTrimFlags() const;
+
+ /// returns a null-terminated string describing the type structure
+ virtual char* getTypeStructure() const;
+ /**
+ The string pointer has to be free using free() by the caller.
+ */
+
+ ///
+ //@}
+
+ /// returns {\tt QT_INTERVAL}
+ virtual QtDataType getDataType() const;
+
+ /// compares data content
+ virtual bool equal( const QtData* obj ) const;
+
+ /// returns content dependent string representation
+ virtual std::string getSpelling() const;
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+
+ private:
+ /// prevents from using the default constructor
+ QtMintervalData(){};
+
+ /// attribute storing the minterval
+ r_Minterval mintervalData;
+
+ /// bitvector indicating real projections
+ vector<bool>* trimFlags;
+};
+
+#include "qlparser/qtmintervaldata.icc"
+
+#endif
+
+
+
+
diff --git a/qlparser/qtmintervaldata.icc b/qlparser/qtmintervaldata.icc
new file mode 100644
index 0000000..b5a003f
--- /dev/null
+++ b/qlparser/qtmintervaldata.icc
@@ -0,0 +1,59 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const r_Minterval&
+QtMintervalData::getMintervalData() const
+{
+ return mintervalData;
+}
+
+
+inline void
+QtMintervalData::setMintervalData( const r_Minterval& minterval )
+{
+ mintervalData = minterval;
+
+ // reset trim flags
+
+ if( trimFlags ) delete trimFlags;
+ trimFlags = new vector<bool>( minterval.dimension() );
+
+ for( int i=0; i<trimFlags->size(); i++ )
+ (*trimFlags)[i] = true;
+}
+
+
+inline const vector<bool>*
+QtMintervalData::getTrimFlags() const
+{
+ return trimFlags;
+}
+
+
diff --git a/qlparser/qtmintervalop.cc b/qlparser/qtmintervalop.cc
new file mode 100644
index 0000000..e112f18
--- /dev/null
+++ b/qlparser/qtmintervalop.cc
@@ -0,0 +1,222 @@
+/*
+* 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, QtMintervalOp: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtmintervalop.cc,v 1.12 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtmintervalop.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtmintervaldata.hh"
+#include "qlparser/qtintervaldata.hh"
+#include "qlparser/qtatomicdata.hh"
+
+#include "catalogmgr/ops.hh"
+#include "relcatalogif/type.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+
+const QtNode::QtNodeType QtMintervalOp::nodeType = QT_MINTERVALOP;
+
+QtMintervalOp::QtMintervalOp( QtOperationList* opList )
+ : QtNaryOperation( opList )
+{
+}
+
+
+
+QtData*
+QtMintervalOp::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtMintervalOp", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtDataList* operandList = NULL;
+
+ if( getOperands( inputList, operandList ) )
+ {
+ vector<QtData*>::iterator dataIter;
+ bool goOn=true;
+
+ // check for point operand
+ if( operandList->size() == 1 && ((*operandList)[0])->getDataType() == QT_MINTERVAL )
+ {
+ // pass point as minterval projection
+ returnValue = (*operandList)[0];
+
+ delete operandList;
+ operandList=NULL;
+ }
+ else
+ {
+ // first check operand types
+ for( dataIter=operandList->begin(); dataIter!=operandList->end() && goOn; dataIter++ )
+ if (!( (*dataIter)->getDataType() == QT_SHORT || (*dataIter)->getDataType() == QT_USHORT ||
+ (*dataIter)->getDataType() == QT_LONG || (*dataIter)->getDataType() == QT_ULONG ||
+ (*dataIter)->getDataType() == QT_OCTET || (*dataIter)->getDataType() == QT_CHAR ||
+ (*dataIter)->getDataType() == QT_INTERVAL))
+ {
+ goOn=false;
+ break;
+ }
+
+ if( !goOn )
+ {
+ RMInit::logOut << "Error: QtMintervalOp::evaluate() - expressions for minterval dimensions must be either of type integer or interval." << endl;
+ parseInfo.setErrorNo(390);
+
+ // delete the old operands
+ if( operandList )
+ {
+ for( dataIter=operandList->begin(); dataIter!=operandList->end(); dataIter++ )
+ if( (*dataIter) ) (*dataIter)->deleteRef();
+
+ delete operandList;
+ operandList=NULL;
+ }
+
+ throw parseInfo;
+ }
+
+ //
+ // create a QtMintervalData object and fill it
+ //
+ r_Minterval domainData( operandList->size() );
+ vector<bool>* trimFlags = new vector<bool>( operandList->size() );
+ int pos;
+
+ for( dataIter=operandList->begin(), pos=0; dataIter!=operandList->end(); dataIter++,pos++ )
+ {
+ if( (*dataIter)->getDataType() == QT_INTERVAL )
+ {
+ domainData << ((QtIntervalData*)(*dataIter))->getIntervalData();
+ (*trimFlags)[pos] = true;
+ }else
+ {
+ if( (*dataIter)->getDataType() == QT_SHORT ||
+ (*dataIter)->getDataType() == QT_LONG ||
+ (*dataIter)->getDataType() == QT_OCTET )
+ domainData << ((QtAtomicData*)(*dataIter))->getSignedValue();
+ else
+ domainData << ((QtAtomicData*)(*dataIter))->getUnsignedValue();
+
+ (*trimFlags)[pos] = false;
+ }
+ }
+
+ returnValue = new QtMintervalData( domainData, trimFlags );
+
+ // delete the old operands
+ if( operandList )
+ {
+ for( dataIter=operandList->begin(); dataIter!=operandList->end(); dataIter++ )
+ if( (*dataIter) ) (*dataIter)->deleteRef();
+
+ delete operandList;
+ operandList=NULL;
+ }
+ }
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtMintervalOp::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtMintervalOp Object " << getNodeType() << endl;
+
+ QtNaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtMintervalOp::printAlgebraicExpression( ostream& s )
+{
+ s << "[";
+
+ QtNaryOperation::printAlgebraicExpression( s );
+
+ s << "]";
+}
+
+
+
+const QtTypeElement&
+QtMintervalOp::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtMintervalOp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ QtOperationList::iterator iter;
+ bool opTypesValid = true;
+
+ for( iter=operationList->begin(); iter!=operationList->end() && opTypesValid; iter++ )
+ {
+ const QtTypeElement& type = (*iter)->checkType( typeTuple );
+
+ // valid types: interval, integers
+ if (!( type.getDataType() == QT_INTERVAL ||
+ type.getDataType() == QT_SHORT ||
+ type.getDataType() == QT_LONG ||
+ type.getDataType() == QT_OCTET ||
+ type.getDataType() == QT_USHORT ||
+ type.getDataType() == QT_ULONG ||
+ type.getDataType() == QT_CHAR))
+ {
+ opTypesValid=false;
+ break;
+ }
+ }
+
+ if( !opTypesValid )
+ {
+ RMInit::logOut << "Error: QtMintervalOp::checkType() - expressions for minterval dimensions must be either of type integer or interval." << endl;
+ parseInfo.setErrorNo(390);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_MINTERVAL );
+
+ return dataStreamType;
+}
diff --git a/qlparser/qtmintervalop.hh b/qlparser/qtmintervalop.hh
new file mode 100644
index 0000000..9d3316e
--- /dev/null
+++ b/qlparser/qtmintervalop.hh
@@ -0,0 +1,81 @@
+#ifndef _QTMINTERVALOP_
+#define _QTMINTERVALOP_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtnaryoperation.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the root of an minterval expression.
+
+*/
+
+class QtMintervalOp : public QtNaryOperation
+{
+ public:
+ /// constructor getting the two operands
+ QtMintervalOp( QtOperationList* opList );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+#include "qlparser/qtmintervalop.icc"
+
+#endif
+
diff --git a/qlparser/qtmintervalop.icc b/qlparser/qtmintervalop.icc
new file mode 100644
index 0000000..3cadc8f
--- /dev/null
+++ b/qlparser/qtmintervalop.icc
@@ -0,0 +1,34 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtMintervalOp::getNodeType() const
+{
+ return nodeType;
+}
diff --git a/qlparser/qtnaryoperation.cc b/qlparser/qtnaryoperation.cc
new file mode 100644
index 0000000..4923004
--- /dev/null
+++ b/qlparser/qtnaryoperation.cc
@@ -0,0 +1,414 @@
+/*
+* 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, QtNaryOperation: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtnaryoperation.cc,v 1.13 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtnaryoperation.hh"
+#include "qlparser/qtconst.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+const QtNode::QtNodeType QtNaryOperation::nodeType = QtNode::QT_NARY_OPERATION;
+
+QtNaryOperation::QtNaryOperation()
+ : QtOperation(),
+ operationList(NULL)
+{
+}
+
+
+QtNaryOperation::QtNaryOperation( QtNode* node )
+ : QtOperation( node ),
+ operationList(NULL)
+{
+}
+
+
+QtNaryOperation::QtNaryOperation( QtOperationList* opList )
+ : QtOperation(),
+ operationList( opList )
+{
+ if( operationList )
+ {
+ QtOperationList::iterator iter;
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++)
+ (*iter)->setParent( this );
+ }
+}
+
+
+QtNaryOperation::~QtNaryOperation()
+{
+ if( operationList )
+ {
+ QtOperationList::iterator iter;
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++)
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+
+ delete operationList;
+ operationList=NULL;
+ }
+}
+
+
+void
+QtNaryOperation::simplify()
+{
+ RMDBCLASS( "QtNaryOperation", "simplify()", "qlparser", __FILE__, __LINE__ )
+
+ // In order to work bottom up, first inspect the descendants
+ QtNode::simplify();
+
+ // Test, if all operands are available.
+ bool success = (operationList != NULL);
+ QtOperationList::iterator iter;
+
+ if( success )
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++)
+ if ((*iter) == NULL)
+ {
+ success = false;
+ break;
+ }
+
+ if( success )
+ {
+ // Test, if all operands are of const type.
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++)
+ if ((*iter)->getNodeType() != QT_CONST)
+ {
+ success = false;
+ break;
+ }
+
+ if( success )
+ {
+ // evaluate the self node with no input list
+ QtData* newConst = this->evaluate( NULL );
+
+ if( newConst )
+ {
+ // create a new constant node and fill it with newConst
+ QtConst* newNode = new QtConst( newConst );
+
+ // set its data stream type
+ newNode->checkType( NULL );
+
+ // link it to the parent
+ getParent()->setInput( this, newNode );
+
+ // delete the self node and its descendants
+ delete this;
+ }
+ }
+ }
+}
+
+
+
+bool
+QtNaryOperation::equalMeaning( QtNode* node )
+{
+ RMDBCLASS( "QtNaryOperation", "equalMeaning( QtNode* )", "qlparser", __FILE__, __LINE__ )
+
+ bool result;
+ result=false;
+
+ if( getNodeType() == node->getNodeType() )
+ {
+ QtNaryOperation* naryNode;
+ naryNode = (QtNaryOperation* ) node; // by force
+
+ // get 2nd operation list
+ QtOperationList* operationList2 = naryNode->getInputs();
+
+ // create iterators
+ QtOperationList::iterator iter, iter2;
+
+ result = true;
+ for( iter =operationList->begin(), iter2 =operationList2->begin();
+ iter!=operationList->end() && iter2!=operationList2->end();
+ iter++, iter2++ )
+ if (!( (*iter)->equalMeaning( *iter2 ) ))
+ {
+ result=false;
+ break;
+ }
+
+ // input lists must have the same length
+ result &= ( iter==operationList->end() && iter2==operationList2->end() );
+ };
+
+ return result;
+}
+
+
+
+QtNode::QtNodeList*
+QtNaryOperation::getChilds( QtChildType flag )
+{
+ RMDBCLASS( "QtNaryOperation", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
+
+ QtNodeList* resultList=NULL;
+ QtNodeList* subList=NULL;
+
+ QtOperationList::iterator iter;
+
+ resultList = new QtNodeList();
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++ )
+ {
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ {
+ subList = (*iter)->getChilds( flag );
+ resultList->splice(resultList->begin(), *subList);
+ delete subList;
+ subList=NULL;
+ };
+
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( *iter );
+ };
+
+ return resultList;
+}
+
+
+bool
+QtNaryOperation::getOperands( QtDataList* inputList, QtDataList* &operandList )
+{
+ RMDBCLASS( "QtNaryOperation", "getOperands( QtDataList*, QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ bool success = (operationList != 0);
+
+ // Test, if all operands are available.
+ QtOperationList::iterator iter;
+
+ if( success )
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++)
+ if ((*iter) == NULL)
+ {
+ success=false;
+ break;
+ }
+
+ if( success )
+ {
+ // get the operands
+ operandList = new QtDataList( operationList->size() );
+
+ int pos=0;
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++)
+ {
+ if( *iter )
+ (*operandList)[pos] = (*iter)->evaluate( inputList );
+
+ pos++;
+ }
+
+ // Test, if all operands are valid.
+ for( pos=0; pos<operandList->size(); pos++ )
+ if ((*operandList)[pos] == NULL)
+ {
+ success=false;
+ break;
+ }
+
+ if( !success )
+ {
+ // if not all operands are valid, delete the old ones
+ QtDataList::iterator dataIter;
+
+ for( dataIter=operandList->begin(); dataIter!=operandList->end(); dataIter++ )
+ if( (*dataIter) ) (*dataIter)->deleteRef();
+
+ delete operandList;
+ operandList = NULL;
+
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtNaryOperation", "Information: QtNaryOperation::getOperands() - at least one operand is not provided." )
+ }
+ }
+ else
+ RMInit::logOut << endl << "Error: QtNaryOperation::getOperands() - at least one operand branch is invalid." << endl;
+
+ return success;
+}
+
+
+
+string
+QtNaryOperation::getSpelling()
+{
+ QtOperationList::iterator iter;
+
+ char tempStr[20];
+ sprintf(tempStr, "%ud", (unsigned long)getNodeType());
+ string result = string(tempStr);
+
+ result.append( "(" );
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++ )
+ {
+ if( iter!=operationList->begin() ) result.append( "," );
+
+ result.append( (*iter)->getSpelling() );
+ }
+
+ result.append( ")" );
+
+ RMDBGONCE(2, RMDebug::module_qlparser, "QtNaryOperation", "Result:" << result.c_str() )
+
+ return result;
+}
+
+
+
+void
+QtNaryOperation::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ QtOperationList::iterator iter;
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++)
+ {
+ if( *iter == inputOld )
+ {
+ (*iter) = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ };
+ };
+};
+
+
+
+QtNode::QtAreaType
+QtNaryOperation::getAreaType()
+{
+ return QT_AREA_SCALAR;
+}
+
+/*
+void
+QtNaryOperation::checkIdempotency()
+{
+ // default method: do nothing
+}
+*/
+
+void
+QtNaryOperation::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtNaryOperation", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ // delete trimList
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ if( operationList )
+ {
+ QtOperationList::iterator iter;
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++)
+ if( *iter )
+ (*iter)->optimizeLoad( new QtNode::QtTrimList );
+ }
+}
+
+
+void
+QtNaryOperation::printTree( int tab, ostream& s, QtChildType mode )
+{
+ if( mode != QT_DIRECT_CHILDS )
+ {
+ if( operationList )
+ {
+ QtOperationList::iterator iter;
+ int no;
+
+ for( no=1, iter=operationList->begin(); iter!=operationList->end(); iter++, no++ )
+ if( *iter )
+ {
+ s << SPACE_STR(tab).c_str() << "input" << no << ": " << endl;
+ (*iter)->printTree( tab+2, s, mode );
+ }
+ }
+ }
+}
+
+
+
+void
+QtNaryOperation::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( operationList )
+ {
+ QtOperationList::iterator iter;
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++ )
+ {
+ if( iter!=operationList->begin() ) s << ",";
+
+ if( *iter )
+ (*iter)->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+ }
+ }
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
diff --git a/qlparser/qtnaryoperation.hh b/qlparser/qtnaryoperation.hh
new file mode 100644
index 0000000..142ea40
--- /dev/null
+++ b/qlparser/qtnaryoperation.hh
@@ -0,0 +1,137 @@
+#ifndef _QTNARYOPERATION_
+#define _QTNARYOPERATION_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include <stdio.h>
+
+#include "qlparser/qtoperation.hh"
+
+/*
+* 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>.
+*/
+/**************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class serves as superclass for all operation classes taking n
+ (more than two) arguments.
+
+*/
+
+class QtNaryOperation : public QtOperation
+{
+ public:
+ /// default constructor
+ QtNaryOperation();
+
+ /// constructor getting the node to the parent
+ QtNaryOperation( QtNode* node );
+
+ /// constructor getting a list of operands
+ QtNaryOperation( QtOperationList* opList );
+
+ /// virtual destructor
+ virtual ~QtNaryOperation();
+
+ /// simplifies the tree
+ virtual void simplify();
+
+ /// test if the two nodes have an equal meaning in the query tree
+ virtual bool equalMeaning( QtNode* node );
+ /**
+ The meaning of a binary operation is equal, iff all operands have
+ the same meaning.
+ */
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// creates a unique name for a subexpression
+ virtual std::string getSpelling();
+
+ /// method for query rewrite
+ virtual void setInput( QtOperation*, QtOperation* inputNew );
+
+ /// tests if the edge to the parent node is of type mdd or atomic
+ virtual QtAreaType getAreaType();
+
+ /// method for checking idempotency rules
+// virtual void checkIdempotency();
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+ /**
+ The method deletes the given {\tt trimList} and passes the {\tt optimizeLoad}
+ message with empty triming lists to its input trees.
+ */
+
+ /// debugging method
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: read/write methods for the operands
+ //@{
+ ///
+ ///
+ inline void setInputs( QtOperationList* opList );
+ ///
+ inline QtNode::QtOperationList* getInputs();
+ ///
+ //@}
+
+ protected:
+ /// method for testing and evaluating the input branches
+ bool getOperands( QtDataList* inputList, QtDataList* &operandList );
+ /**
+ The method checks if the input branches are valid. Then it passes the evaluate message to its two
+ operands with the {\tt inputList} as argument. The returned results are provided through the arguments
+ {\tt operand1} and {\tt operand2} called by reference. The method returns {\tt true} if the operands are
+ valid, otherwise {\tt false}.
+ */
+
+ /// operation trees
+ QtOperationList* operationList;
+
+ private:
+ /// atribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtnaryoperation.icc"
+
+#endif
+
+
diff --git a/qlparser/qtnaryoperation.icc b/qlparser/qtnaryoperation.icc
new file mode 100644
index 0000000..18f104c
--- /dev/null
+++ b/qlparser/qtnaryoperation.icc
@@ -0,0 +1,50 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline void
+QtNaryOperation::setInputs( QtOperationList* opList )
+{
+ operationList = opList;
+
+ if( operationList )
+ {
+ QtOperationList::iterator iter;
+
+ for( iter=operationList->begin(); iter!=operationList->end(); iter++ )
+ if( *iter )
+ (*iter)->setParent( this );
+ }
+};
+
+
+inline QtNode::QtOperationList*
+QtNaryOperation::getInputs()
+{
+ return operationList;
+};
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;
+}
+
+
+
+
diff --git a/qlparser/qtnode.hh b/qlparser/qtnode.hh
new file mode 100644
index 0000000..53a038e
--- /dev/null
+++ b/qlparser/qtnode.hh
@@ -0,0 +1,503 @@
+#ifndef _QTNODE_
+#define _QTNODE_
+
+#ifndef CPPSTDLIB
+#include <vector.h> // STL<ToolKit>
+#include <list.h> // STL<ToolKit>
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <vector>
+#include <list>
+#include <string>
+#endif
+
+#include "raslib/rmdebug.hh"
+#include "raslib/sinterval.hh"
+#include "qlparser/parseinfo.hh"
+#include "qlparser/qtdata.hh"
+
+// define used in lots of qlparser files to indent output
+#ifdef CPPSTDLIB
+#define SPACE_STR(numSpace) std::string(numSpace,' ')
+#else
+#define SPACE_STR(numSpace) std::string(' ',numSpace)
+#endif
+
+class QtOperation; // forward declarations of subclasses of QtNode
+class Type;
+class QtTypeElement;
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/**
+
+ The class QtNode is the common super class of all node
+ classes of the query tree. It provides a reference to its
+ parent node in the tree. The parent of root is null.
+
+*/
+
+
+class QtNode
+{
+ public:
+ /// list of QtData pointers
+ typedef std::vector<QtData*> QtDataList;
+
+ /// struct containing dimension and triming information
+ struct QtTrimElement
+ {
+ r_Dimension dimension;
+ r_Sinterval interval;
+ bool intervalFlag;
+ };
+
+ /// list of QtTrimData structures
+ typedef std::vector<QtTrimElement*> QtTrimList;
+
+ /// list of QtNode pointers
+ typedef std::list<QtNode*> QtNodeList;
+
+ enum QtNodeType
+ {
+ QT_UNDEFINED_NODE,
+ QT_MDD_ACCESS,
+ QT_OPERATION_ITERATOR,
+ QT_SELECTION_ITERATOR,
+ QT_JOIN_ITERATOR,
+ QT_UPDATE,
+ QT_INSERT,
+ QT_DELETE,
+ QT_COMMAND,
+ QT_PLUS,
+ QT_MINUS,
+ QT_MULT,
+ QT_DIV,
+ QT_OR,
+ QT_AND,
+ QT_XOR,
+ QT_IS,
+ QT_EQUAL,
+ QT_NOT_EQUAL,
+ QT_LESS,
+ QT_LESS_EQUAL,
+ QT_NOT,
+ QT_SQRT,
+// added by CStancuMara
+ QT_EXECUTE,
+ QT_ONC_STREAM,
+ QT_ITERATOR,
+ QT_OPERATION,
+ QT_BINARY_OPERATION,
+ QT_BINARY_INDUCE,
+ QT_GROUP_ITERATOR,
+ QT_IDENT,
+ QT_NARY_OPERATION,
+ QT_UNARY_OPERATION,
+ QT_CONDENSE,
+ QT_UNARY_INDUCE,
+
+//**************
+ QT_ABS, QT_EXP, QT_LOG, QT_LN, QT_SIN, QT_COS,
+ QT_TAN, QT_SINH, QT_COSH, QT_TANH, QT_ARCSIN,
+ QT_ARCCOS, QT_ARCTAN,
+ QT_REALPART,
+ QT_IMAGINARPART,
+ QT_CAST,
+//**************
+
+ QT_CSE_ROOT,
+ QT_DOMAIN_OPERATION,
+ QT_ALL,
+ QT_SOME,
+ QT_COUNTCELLS,
+ QT_ADDCELLS,
+ QT_AVGCELLS,
+ QT_MINCELLS,
+ QT_MAXCELLS,
+ QT_MDD_VAR,
+ QT_MDD_STREAM,
+ QT_CONST,
+ QT_DOT,
+ QT_CONVERSION,
+ QT_OID,
+ QT_INTERVALOP,
+ QT_MINTERVALOP,
+ QT_POINTOP,
+ QT_LO,
+ QT_HI,
+ QT_SDOM,
+ QT_SHIFT,
+ QT_EXTEND,
+ //QT_MINTERVAL_SELECT,
+ QT_MARRAYOP,
+ QT_CONDENSEOP,
+ QT_SCALE,
+ QT_OVERLAY,
+ QT_BIT,
+ QT_PYRAMID,
+ QT_LAST_NODE_TYPE
+ };
+
+
+
+ enum QtAreaType
+ {
+ QT_AREA_MDD,
+ QT_AREA_SCALAR
+ };
+
+ enum QtChildType
+ {
+ QT_DIRECT_CHILDS,
+ QT_LEAF_NODES,
+ QT_ALL_NODES
+ };
+
+ /// list of QtOperation pointers
+ typedef std::vector<QtOperation*> QtOperationList;
+
+ /// default constructor
+ QtNode();
+
+ /// constructor getting a pointer to the parent
+ QtNode( QtNode* node );
+
+ /// destructor
+ virtual ~QtNode();
+
+ /// returns weather class b is a subtype of class a
+ bool subtype( enum QtNodeType a, enum QtNodeType b );
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+ /**
+ The method allows different retrieval of the subtree nodes. Dependent on the content of {\tt flag}
+ one of the following semantics is used:
+ {\tt DIRECT_CHILDS} - A list of all direct child nodes of the current node is returned.
+ {\tt LEAF_NODES } - A list of all leaf nodes of the subtree with the current node as root is returned.
+ {\tt ALL_NODES } - A list of all nodes of the subtree with the current node as root is returned.
+ The nodes in the result list have a special order. Every node comes before its parent node in
+ the result list.
+ */
+
+ /// return childs of a certain class
+ QtNodeList* getChild( const QtNodeType node, QtChildType flag = QT_DIRECT_CHILDS );
+ /**
+ The method allows to specify the class of childs to be considered according to method {\tt getChilds}.
+ By default, just direct childs are considered
+ */
+
+ /// test if the two nodes have an equal meaning in a subtree
+ virtual bool equalMeaning( QtNode* node );
+
+ /**
+ The method checks, if the two nodes have an equal meaning in a subtree.
+ {\tt equalMeaning()} depends on the type of the node and the information in the node.
+ For unary and binary operators the method {\tt equalMeaning()} is invoked on the input nodes.
+ */
+
+ /// creates a unique name for a common subexpression
+ virtual std::string getSpelling();
+
+ /**
+ The method creates a unique name for common subexpressions by concatenating operators
+ and variables in the subtree of the common subexpression.
+ */
+
+ /// test if the edge to the parent node is of type mdd or atomic
+ virtual QtAreaType getAreaType();
+ /**
+ The method tests if the edge to the parent node belongs to a multidimensional or
+ atomic area.
+ */
+
+ /// simplifies the tree
+ virtual void simplify();
+ /**
+ The method evaluates constant expressions.
+ */
+
+ /// optimizes the tree
+// virtual void rewriteOps();
+ /**
+ The method applies some algebraic rules:
+
+ \begin{verbatim}
+ some( x or y ) -> some( x ) or some( y )
+ all ( x and y ) -> all ( x ) and all ( y )
+ all() or some() -> some() or all()
+ some() and all() -> all() and some()
+ \end{verbatim}
+
+ Further, a left deep tree is produced (for +,*)::
+
+ \begin{verbatim}
+ (T1 o T2) + (T3 o T4) -> ((T1 o T2) o T3) o T4
+ \end{verbatim}
+
+ The method has to be supplied top-down in the query tree.
+ */
+
+ /// optimizes the tree
+// virtual void sortAssociativeOps();
+ /**
+ Operators of commutative binary operations are ordered in a
+ unique sequence.
+ */
+
+ /// check idempetency rules
+// virtual void checkIdempotency();
+ /**
+ The method applies idempotency rules on binary operations.
+ The method is supplied bottom-up in the query tree.
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES )=0;
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout )=0;
+
+ //@Man: Read/Write methods
+ //@{
+ ///
+
+ ///
+ inline virtual void setInput( QtOperation* inputOld, QtOperation* inputNew);
+ ///
+ inline QtNode* getParent() const;
+ ///
+ inline void setParent( QtNode* node );
+ ///
+ inline const ParseInfo& getParseInfo();
+ ///
+ inline void setParseInfo( const ParseInfo &info );
+
+ ///
+ //@}
+
+ /// methods for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+ /**
+ The method allows you to differ between the different node types.
+ */
+
+ /// method for pre optimizations (basically load optimization)
+ //virtual void preOptimize(){};
+ /**
+ {\em Load Optimization}
+ The method is invoked through the whole query tree. The information of
+ every triming and projection node is collected and stored in a {\tt QtTrimList}
+ structure which is passed down. While collecting the information consistency
+ of the data is checked. At the leafs, which are load operations, the structure
+ is converted to a minterval object and stored in the leaf node.
+ The list is dynamically created in the node which is on top of an operation subtree
+ and deleted where the information is stored or dropped.
+
+ Defined empty to do nothing in case it is not defined for a subclass.
+ */
+
+ /// returns the QtNodeType parent of the argument (do not use for the root)
+ enum QtNodeType getQtNodeTypeParent(enum QtNodeType);
+
+ /// number of QtNodeTypes
+ static const int QtNodes;
+
+ /// the root of the inheritance tree
+ static const QtNodeType QtRoot;
+
+ /// the inheritance relations list
+ static const QtNodeType QtInheritance[][2];
+
+
+ protected:
+ /// attribute for parser info
+ ParseInfo parseInfo;
+
+ private:
+ /// pointer to its parent
+ QtNode* parent;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+
+ /// (base_class, derived_class) pair
+ struct QtNodePair {
+ enum QtNodeType base, deriv;
+ };
+
+
+ ///operator overload for QtNodePair struct
+ friend bool operator<( const QtNodePair a, const QtNodePair b);
+
+ /// starting point of elements having node as base class
+ static int child_range[];
+
+ /// sets up the child_range[] array
+ void set_child_range(const QtNodePair *arr);
+
+ /// minim and maxim labels to determine subtypes
+ static int minim[], maxim[];
+
+ /// keeps track if SetMinMax was already called
+ static bool MinMaxDone;
+
+ /// sets minim and maxim values for each QtNodeType
+ void SetMinMax();
+
+ /// sets min max values once child_range is set up, for subtree with x as root
+ void num_node (const QtNodePair *arr, enum QtNodeType x);
+
+};
+
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/**
+
+ The class encapsulates type information. It additionally
+ can hold a name in order to be identifyable in a list.
+
+ The type is specified by {\tt dataType} and {\tt type}.
+ This is necessary because not all types are supported by
+ subclasses of \Ref{Type}, e.g. not all types are persistent ones.
+
+ In case of QT_MDD and QT_COMPLEX, further type information
+ can be optained from {\tt type}.
+
+*/
+
+class QtTypeElement
+{
+ public:
+ ///
+ QtTypeElement();
+
+ ///
+ QtTypeElement( const QtDataType initDataType, const char* initName = NULL );
+
+ ///
+ QtTypeElement( const Type* initType, const char* initName = NULL );
+
+ ///
+ QtTypeElement( const QtTypeElement& typeElement );
+
+ ///
+ ~QtTypeElement();
+
+ /// assignment: cleanup + copy
+ const QtTypeElement& operator= ( const QtTypeElement& );
+
+ //@Man: Read/Write methods
+ //@{
+ ///
+ ///
+ void setDataType( const QtDataType newDataType );
+ ///
+ void setType( const Type* newType );
+ ///
+ inline void setName( const char* newName );
+ ///
+ inline const QtDataType getDataType() const;
+ ///
+ inline const Type* getType() const;
+ ///
+ inline const char* getName() const;
+ ///
+ inline bool isBaseType() const;
+ ///
+ inline bool isInteger() const;
+ ///
+ //@}
+ ///
+
+ /// print type
+ void printStatus( std::ostream& s = std::cout ) const;
+
+ private:
+ ///
+ QtDataType dataType;
+
+ ///
+ const Type* type;
+
+ ///
+ char* name;
+};
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/**
+
+ The class encapsulates a tuple of \Ref{QtTypeElement}
+ objects.
+
+*/
+
+class QtTypeTuple
+{
+ public:
+ ///
+ QtTypeTuple( unsigned int length = 0 );
+
+ /// concatenate type tuple
+ void concat( const QtTypeTuple& typeTuple );
+
+ /// concatenate type element
+ void concat( const QtTypeElement& typeElement );
+
+ ///
+ std::vector<QtTypeElement> tuple;
+
+ /// print type
+ void printStatus( std::ostream& s = std::cout ) const;
+};
+
+#include "qlparser/qtnode.icc"
+
+#endif
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtnode.icc b/qlparser/qtnode.icc
new file mode 100644
index 0000000..0bdddeb
--- /dev/null
+++ b/qlparser/qtnode.icc
@@ -0,0 +1,130 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <cstdlib>
+#include <cstring>
+
+inline QtNode*
+QtNode::getParent() const
+{
+ return parent;
+};
+
+
+inline void
+QtNode::setParent( QtNode* node )
+{
+ parent = node;
+};
+
+
+inline const QtNode::QtNodeType
+QtNode::getNodeType() const
+{
+ return nodeType;
+}
+
+
+
+inline void
+QtNode::setInput( QtOperation* , QtOperation* )
+{
+ RMInit::logOut << "Error: Method setInput(...) is undefined for node type " << getNodeType() << " in the query tree." << endl;
+}
+
+
+inline const ParseInfo&
+QtNode::getParseInfo()
+{
+ return parseInfo;
+}
+
+
+inline void
+QtNode::setParseInfo( const ParseInfo &info )
+{
+ parseInfo = info;
+}
+
+
+
+inline void
+QtTypeElement::setName( const char* newName )
+{
+ if( name ) free( name );
+ name = strdup( newName );
+}
+
+
+
+
+inline const QtDataType
+QtTypeElement::getDataType() const
+{
+ return dataType;
+}
+
+
+
+inline const Type*
+QtTypeElement::getType() const
+{
+ return type;
+}
+
+
+inline const char*
+QtTypeElement::getName() const
+{
+ return name;
+}
+
+
+inline bool
+QtTypeElement::isBaseType() const
+{
+ return dataType == QT_BOOL || dataType == QT_COMPLEX ||
+ dataType == QT_CHAR || dataType == QT_OCTET ||
+ dataType == QT_USHORT || dataType == QT_SHORT ||
+ dataType == QT_ULONG || dataType == QT_LONG ||
+ dataType == QT_FLOAT || dataType == QT_DOUBLE ||
+ dataType == QT_COMPLEXTYPE1 || dataType == QT_COMPLEXTYPE2;
+}
+
+
+
+inline bool
+QtTypeElement::isInteger() const
+{
+ return dataType == QT_CHAR || dataType == QT_OCTET ||
+ dataType == QT_USHORT || dataType == QT_SHORT ||
+ dataType == QT_ULONG || dataType == QT_LONG;
+}
+
+
diff --git a/qlparser/qtoid.cc b/qlparser/qtoid.cc
new file mode 100644
index 0000000..6b6d01b
--- /dev/null
+++ b/qlparser/qtoid.cc
@@ -0,0 +1,179 @@
+/*
+* 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, QtOId: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtoid.cc,v 1.13 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtoid.hh"
+#include "qlparser/qtvariable.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtmdd.hh"
+
+#include "mddmgr/mddobj.hh"
+
+#include "raslib/oid.hh"
+
+const QtNode::QtNodeType QtOId::nodeType = QtNode::QT_OID;
+
+
+QtOId::QtOId( QtVariable* newInput )
+ : QtUnaryOperation( newInput )
+{
+ RMDBCLASS( "QtOId", "QtOId( QtVariable* )", "qlparser", __FILE__, __LINE__ )
+}
+
+
+
+QtData*
+QtOId::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtOId", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ operand = input->evaluate( inputList );
+
+ if( operand )
+ {
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() == QT_MDD )
+ {
+ RMInit::logOut << "Internal error in QtOId::evaluate() - "
+ << "runtime type checking failed (MDD)." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ QtMDD* qtMDD = (QtMDD*) operand;
+ MDDObj* mddObj = qtMDD->getMDDObject();
+
+ if( mddObj->isPersistent() )
+ {
+ MDDObj* persMDD = (MDDObj*) mddObj;
+
+ // get local oid and pass it as double
+ OId localOId;
+ if( !persMDD->getOId( &localOId ) )
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtOid", " oid = " << (double)localOId )
+
+ returnValue = new QtAtomicData( (double)localOId, (unsigned short)8 );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtOId::evaluate() - could not get oid." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ parseInfo.setErrorNo(384);
+ throw parseInfo;
+ }
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtOId::evaluate() - operand is not a persistent MDD." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ parseInfo.setErrorNo(383);
+ throw parseInfo;
+ }
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+ else
+ RMInit::logOut << "Error: QtOId::evaluate() - operand is not provided." << std::endl;
+
+ return returnValue;
+}
+
+
+
+void
+QtOId::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtOId Object: " << std::endl;
+
+ QtUnaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtOId::printAlgebraicExpression( std::ostream& s )
+{
+ s << "oid(" << std::flush;
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtTypeElement&
+QtOId::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtOId", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input type
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ if( inputType.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtOId::checkType() - operand is not of type MDD." << std::endl;
+ parseInfo.setErrorNo(383);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_DOUBLE );
+ }
+ else
+ RMInit::logOut << "Error: QtOId::checkType() - operand branch invalid." << std::endl;
+
+ return dataStreamType;
+}
diff --git a/qlparser/qtoid.hh b/qlparser/qtoid.hh
new file mode 100644
index 0000000..03dbbdb
--- /dev/null
+++ b/qlparser/qtoid.hh
@@ -0,0 +1,78 @@
+#ifndef _QTOID_HH__
+#define _QTOID_HH___
+
+#include "qlparser/qtunaryoperation.hh"
+
+
+// forward declarations
+class QtVariable;
+
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents an oid node.
+
+*/
+
+class QtOId : public QtUnaryOperation
+{
+ public:
+ /// constructor getting operand
+ QtOId( QtVariable* newInput );
+
+ /// evaluates the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtoid.icc"
+
+#endif
+
diff --git a/qlparser/qtoid.icc b/qlparser/qtoid.icc
new file mode 100644
index 0000000..8efdc80
--- /dev/null
+++ b/qlparser/qtoid.icc
@@ -0,0 +1,35 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const QtNode::QtNodeType
+QtOId::getNodeType() const
+{
+ return nodeType;
+}
diff --git a/qlparser/qtoncstream.cc b/qlparser/qtoncstream.cc
new file mode 100644
index 0000000..53e72c2
--- /dev/null
+++ b/qlparser/qtoncstream.cc
@@ -0,0 +1,49 @@
+/*
+* 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, QtONCStream: $Id: qtoncstream.cc,v 1.10 1997/09/04 14:34:46 ritsch Exp $";
+
+#include "qlparser/qtoncstream.hh"
+
+const QtNode::QtNodeType QtONCStream::nodeType = QtNode::QT_ONC_STREAM;
+
+QtONCStream::QtONCStream()
+ : QtNode()
+{
+}
+
+
+QtONCStream::QtONCStream( QtNode* node )
+ : QtNode( node )
+{
+}
+
diff --git a/qlparser/qtoncstream.hh b/qlparser/qtoncstream.hh
new file mode 100644
index 0000000..d267d7a
--- /dev/null
+++ b/qlparser/qtoncstream.hh
@@ -0,0 +1,102 @@
+#ifndef _QTONCSTREAM_
+#define _QTONCSTREAM_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtnode.hh"
+
+/*
+* 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>.
+*/
+/************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+This class is super class for every class supporting the ONC protocol
+which means that, first, a stream has to be opened with open(),
+then the elements are received through invoking next(),
+and at the end, the stream is closed with the close() method. The
+next() method returns a tupel of QtData or any subclass of QtData.
+
+*/
+
+class QtONCStream : public QtNode
+{
+ public:
+ /// default constructor
+ QtONCStream();
+
+ /// constructor getting a pointer to the parent
+ QtONCStream( QtNode* node );
+
+ //@Man: Operations of the ONC protocol
+ //@{
+ ///
+ virtual void open()=0;
+ ///
+ virtual QtDataList* next()=0;
+ ///
+ virtual void close()=0;
+ ///
+ virtual void reset()=0;
+ //@}
+
+ /// type checking of the subtree
+ virtual const QtTypeTuple& checkType() = 0;
+ /**
+ The method triggers type checking of the node's subtree. If an error occurs, an exception
+ is raised.
+ */
+
+ //@Man: Read/Write methods
+ //@{
+ ///
+ ///
+ inline void setDataStreamType( const QtTypeTuple& type );
+ ///
+ inline const QtTypeTuple& getDataStreamType() const;
+ ///
+ //@}
+
+ protected:
+ /// result type of the node
+ QtTypeTuple dataStreamType;
+
+ private:
+ /// atribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#endif
+
diff --git a/qlparser/qtoncstream.icc b/qlparser/qtoncstream.icc
new file mode 100644
index 0000000..e1d59df
--- /dev/null
+++ b/qlparser/qtoncstream.icc
@@ -0,0 +1,42 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline void
+QtONCStream::setDataStreamType( const QtTypeTuple &type )
+{
+ dataStreamType = type;
+}
+
+
+
+inline const QtTypeTuple&
+QtONCStream::getDataStreamType() const
+{
+ return dataStreamType;
+}
diff --git a/qlparser/qtoperation.cc b/qlparser/qtoperation.cc
new file mode 100644
index 0000000..23bf378
--- /dev/null
+++ b/qlparser/qtoperation.cc
@@ -0,0 +1,126 @@
+/*
+* 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, QtOperation: $Id: qtoperation.cc,v 1.17 2002/06/05 18:18:17 coman Exp $";
+
+
+#include "qlparser/qtoperation.hh"
+
+#include <iostream>
+
+const QtNode::QtNodeType QtOperation::nodeType = QtNode::QT_OPERATION;
+
+QtOperation::QtOperation()
+ : QtNode()
+{
+}
+
+
+QtOperation::QtOperation( QtNode* node )
+ : QtNode( node )
+{
+}
+
+
+QtOperation*
+QtOperation::getUniqueOrder( const QtNode::QtNodeType )
+{
+ // default method;
+
+ return this;
+}
+
+
+QtData*
+QtOperation::evaluate( QtDataList* /*inputList*/ )
+{
+ RMInit::logOut << "Error: Method evaluate(...) is undefined for a node in the query tree." << std::endl;
+ return NULL;
+}
+
+
+void
+QtOperation::optimizeLoad( QtTrimList* trimList )
+{
+ if( trimList )
+ {
+ std::vector<QtNode::QtTrimElement*>::iterator iter;
+ for( iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+ }
+
+ RMInit::logOut << "Error: Method optimizeLoad(...) is undefined for a QtOperation node in the query tree." << std::endl;
+}
+
+
+
+const QtTypeElement&
+QtOperation::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtOperation", "checkType( QtTypeElement, QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ return dataStreamType;
+}
+
+
+void
+QtOperation::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtOperation Object: type " << std::flush;
+ dataStreamType.printStatus( s );
+ s << std::endl;
+
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ {
+ s << SPACE_STR(tab).c_str() << "no operation" << std::endl;
+ }
+
+}
+
+
+
+void
+QtOperation::printAlgebraicExpression( std::ostream& s )
+{
+ s << "op<";
+
+ s << "no ops";
+
+ s << ">";
+}
diff --git a/qlparser/qtoperation.hh b/qlparser/qtoperation.hh
new file mode 100644
index 0000000..eab3d7e
--- /dev/null
+++ b/qlparser/qtoperation.hh
@@ -0,0 +1,120 @@
+#ifndef _QTOPERATION_
+#define _QTOPERATION_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtnode.hh"
+
+class QtData; // forward declaration of a subclass of QtOperation
+
+#include <iostream>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+QtOperation defines a method {\tt evaluate()} getting a tupel of {\tt QtData} and returning
+a {\tt QtData} element. Every subclass has to redefine this method to compute its specific
+operation. Therefore, it takes its inputs which are also of type {\tt QtOperation}, and
+invokes the {\tt evaluate()} method again. The results are used as operands and the
+computed value is returned.
+
+*/
+
+class QtOperation : public QtNode
+{
+ public:
+ /// default constructor
+ QtOperation();
+
+ /// constructor getting a pointer to the parent
+ QtOperation( QtNode* parent );
+
+ ///for associative law
+ virtual QtOperation* getUniqueOrder( const QtNode::QtNodeType ID );
+
+ /**
+ The method gives back a node that has the same QtNodeType and has the lowest
+ Spelling of all nodes in the subtree with the same QtNodeType.
+ */
+
+ /// method for evaluating the node
+ virtual QtData* evaluate( QtDataList* inputList );
+
+ /**
+ The method takes the {\tt inputList} to compute the result of the node which is returned in the end.
+ The semantics is that elements of the {\tt inputList} are not allowed to be used as a result because
+ the {\tt inputList} is freed by the caller. If this is needed, they have to be copied.
+ */
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+ /**
+ The method triggers type checking of the node's subtree. If an error occurs, an exception
+ is raised.
+ */
+
+ //@Man: Read/Write methods
+ //@{
+ ///
+ ///
+ inline void setDataStreamType( const QtTypeElement& type );
+ ///
+ inline const QtTypeElement& getDataStreamType() const;
+ ///
+ //@}
+
+ void printTree( int tab, std::ostream& s, QtChildType mode=QT_ALL_NODES );
+
+ void printAlgebraicExpression( std::ostream& s );
+
+ protected:
+ /// result type of the node
+ QtTypeElement dataStreamType;
+
+ private:
+ /// atribute for indetification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtoperation.icc"
+
+#endif
+
+
diff --git a/qlparser/qtoperation.icc b/qlparser/qtoperation.icc
new file mode 100644
index 0000000..c5703c1
--- /dev/null
+++ b/qlparser/qtoperation.icc
@@ -0,0 +1,43 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline void
+QtOperation::setDataStreamType( const QtTypeElement &type )
+{
+ dataStreamType = type;
+}
+
+
+
+inline const QtTypeElement&
+QtOperation::getDataStreamType() const
+{
+ return dataStreamType;
+}
diff --git a/qlparser/qtoperationiterator.cc b/qlparser/qtoperationiterator.cc
new file mode 100644
index 0000000..6a1008a
--- /dev/null
+++ b/qlparser/qtoperationiterator.cc
@@ -0,0 +1,303 @@
+/*
+* 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, QtOperationIterator: $Id: qtoperationiterator.cc,v 1.24 2001/08/07 12:36:49 barbat Exp $";
+
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtoperationiterator.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtdata.hh"
+
+#include <iostream>
+#include <string>
+#include <vector>
+using namespace std;
+
+const QtNode::QtNodeType QtOperationIterator::nodeType = QT_OPERATION_ITERATOR;
+
+
+QtOperationIterator::QtOperationIterator()
+ : QtIterator()
+{
+ operationTreeList = new QtOperationList();
+}
+
+
+QtOperationIterator::QtOperationIterator( QtNode* node )
+ : QtIterator( node )
+{
+ operationTreeList = new QtOperationList();
+}
+
+
+QtOperationIterator::~QtOperationIterator()
+{
+ // release( operationTreeList->begin(), operationTreeList->end() );
+ QtOperationList::iterator iter;
+ for( iter = operationTreeList->begin(); iter!=operationTreeList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete operationTreeList;
+ operationTreeList=NULL;
+}
+
+
+QtNode::QtNodeList*
+QtOperationIterator::getChilds( QtChildType flag )
+{
+ RMDBCLASS( "QtOperationIterator", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
+
+ QtNodeList* resultList=NULL;
+ QtNodeList* subList=NULL;
+
+ QtOperationList::iterator iter;
+
+ resultList = QtIterator::getChilds( flag );
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtOperationIterator", \
+ RMInit::dbgOut << "1. childs from stream subtree " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); )
+
+ for( iter=operationTreeList->begin(); iter!=operationTreeList->end(); iter++ )
+ {
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ {
+ subList = (*iter)->getChilds( flag ) ;
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtOperationIterator", \
+ RMInit::dbgOut << "2. childs from operation subtree (without direct childs) " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=subList->begin(); debugIter!=subList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); )
+
+ // remove all elements in subList and insert them at the beginning of resultList
+ resultList->splice( resultList->begin(), *subList );
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtOperationIterator", \
+ RMInit::dbgOut << "3. merge of the lists " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); )
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtOperationIterator", \
+ RMInit::dbgOut << "4. old list (must be empty)" << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=subList->begin(); debugIter!=subList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); )
+
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ };
+
+ // add nodes of next level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( *iter );
+
+RMDBGIF(3, RMDebug::module_qlparser, "QtOperationIterator", \
+ RMInit::dbgOut << "4. current child list including direct childs " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); )
+
+ };
+
+ return resultList;
+}
+
+
+void
+QtOperationIterator::printTree( int tab, ostream& s, QtChildType mode )
+{
+ QtOperationList::iterator iter;
+
+ s << SPACE_STR(tab).c_str() << "QtOperationIterator Object: type " << flush;
+ dataStreamType.printStatus( s );
+ s << endl;
+
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ {
+ if( operationTreeList->empty() )
+ s << SPACE_STR(tab).c_str() << "no operation" << endl;
+ else
+ for( iter=operationTreeList->begin(); iter!=operationTreeList->end(); iter++ )
+ {
+ s << SPACE_STR(tab).c_str() << "operation: " << endl;
+ (*iter)->printTree( tab + 2, s, mode );
+ }
+ }
+
+ QtIterator::printTree( tab, s, mode );
+}
+
+
+
+void
+QtOperationIterator::printAlgebraicExpression( ostream& s )
+{
+ s << "op<";
+
+ if( operationTreeList )
+ {
+ for( int i=0; i<operationTreeList->size(); i++ )
+ {
+ (*operationTreeList)[i]->printAlgebraicExpression( s );
+
+ if( i < operationTreeList->size()-1 )
+ s << ", ";
+ }
+ }
+ else
+ s << "no ops";
+
+ s << ">";
+
+ QtIterator::printAlgebraicExpression( s );
+}
+
+
+
+QtNode::QtDataList*
+QtOperationIterator::next()
+{
+ RMDBCLASS( "QtOperationIterator", "next()", "qlparser", __FILE__, __LINE__ )
+
+ QtDataList* returnValue = NULL;
+
+ if( inputs )
+ {
+ QtDataList* nextTupel=NULL;
+ QtDataList* resultList=NULL;
+
+ // create a composed tupel of type QtDataList of the next elements of the input streams
+ // right now, just take the QtDataList vector of the first input stream
+ nextTupel = (*inputs)[0]->next();
+
+ if( nextTupel )
+ {
+ QtOperationList::iterator iter;
+ vector<QtData*>::iterator dataIter;
+
+ resultList = new QtDataList( operationTreeList->size() );
+
+ int pos=0;
+
+ for( iter=operationTreeList->begin(); iter!=operationTreeList->end(); iter++)
+ {
+ // send them through the operand tree
+
+ try
+ {
+ if( *iter )
+ (*resultList)[pos] = (*iter)->evaluate( nextTupel );
+ }
+ catch(...)
+ {
+ // Delete the tupel vector received by next(). Just tupel elements which are not
+ // further referenced are deleted.
+ for( dataIter=nextTupel->begin(); dataIter!=nextTupel->end(); dataIter++ )
+ if( (*dataIter) ) (*dataIter)->deleteRef();
+
+ for (QtDataList::iterator deleteIter = resultList->begin(); deleteIter != resultList->end(); deleteIter++)
+ {
+ delete *deleteIter;
+ *deleteIter = NULL;
+ }
+ delete resultList;
+ resultList = NULL;
+ delete nextTupel;
+ nextTupel = NULL;
+
+ throw;
+ }
+
+ pos++;
+ }
+
+ // Delete the tupel vector received by next(). Just tupel elements which are not
+ // further referenced are deleted.
+ for( dataIter=nextTupel->begin(); dataIter!=nextTupel->end(); dataIter++ )
+ if( (*dataIter) ) (*dataIter)->deleteRef();
+
+ // ... and now the vector itself
+ delete nextTupel;
+ nextTupel=NULL;
+
+ returnValue = resultList;
+ }
+ }
+ return returnValue;
+}
+
+/*
+void
+QtOperationIterator::preOptimize()
+{
+ QtOperationList::iterator iter;
+
+ for( iter=operationTreeList->begin(); iter!=operationTreeList->end(); iter++ )
+ (*iter)->optimizeLoad( new QtNode::QtTrimList );
+
+ // pass it to the input streams
+ QtIterator::preOptimize();
+};
+*/
+
+
+const QtTypeTuple&
+QtOperationIterator::checkType()
+{
+ RMDBCLASS( "QtOperationIterator", "checkType()", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType = QtTypeTuple();
+
+ QtTypeTuple inputTypeTuple;
+
+ getInputTypeTuple( inputTypeTuple );
+
+ // type check of operation trees
+ QtOperationList::iterator iter;
+
+ for( iter=operationTreeList->begin(); iter!=operationTreeList->end(); iter++ )
+ if( *iter )
+ dataStreamType.concat( (*iter)->checkType( &inputTypeTuple ) );
+
+ return dataStreamType;
+}
+
+
diff --git a/qlparser/qtoperationiterator.hh b/qlparser/qtoperationiterator.hh
new file mode 100644
index 0000000..78ab11e
--- /dev/null
+++ b/qlparser/qtoperationiterator.hh
@@ -0,0 +1,120 @@
+#ifndef _QTOPERATIONITERATOR_
+#define _QTOPERATIONITERATOR_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtiterator.hh"
+#include "qlparser/qtoperation.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+A QtOperationIterator takes the next element of its input streams an creates
+a tupel out of them. The operation specified through an operation tree of type
+QtOperation is evaluated for this tupel and the result is passed to its output
+stream. The class stands for the SELECT part of a query. The operations in the
+SELECT clause are expressed through an operation tree which is attached to this
+class.
+
+*/
+
+class QtOperationIterator : public QtIterator
+{
+ public:
+ /// default constructor
+ QtOperationIterator();
+
+ /// constructor getting a pointer to the parent
+ QtOperationIterator( QtNode* node );
+
+ /// virtual destructor
+ virtual ~QtOperationIterator();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// method for query rewrite
+ inline virtual void setInput( QtOperation* child, QtOperation* input);
+
+ /// optimizing load access
+ //virtual void preOptimize();
+ /**
+ Trigger load optimization in the operation tree and pass the optimization step to
+ the input streams.
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ //inline virtual void setParents();
+ ///
+ inline void setOperationTree( QtOperation* operation );
+ ///
+ inline QtNode::QtOperationList* getOperationTreeList();
+ //@}
+
+ //@Man: Operations of the ONC protocol:
+ //@{
+ ///
+ QtDataList* next();
+ //@}
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking
+ virtual const QtTypeTuple& checkType();
+
+ private:
+ /// operation trees
+ QtOperationList* operationTreeList;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtoperationiterator.icc"
+
+#endif
+
diff --git a/qlparser/qtoperationiterator.icc b/qlparser/qtoperationiterator.icc
new file mode 100644
index 0000000..4abe3fc
--- /dev/null
+++ b/qlparser/qtoperationiterator.icc
@@ -0,0 +1,74 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline void
+QtOperationIterator::setOperationTree( QtOperation* operation )
+{
+ if( operation )
+ {
+ operationTreeList->push_back( operation );
+ operation->setParent( this );
+ };
+};
+
+
+
+inline QtNode::QtOperationList*
+QtOperationIterator::getOperationTreeList()
+{
+ return( operationTreeList );
+};
+
+
+
+inline void
+QtOperationIterator::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ QtOperationList::iterator iter;
+
+ for( iter=operationTreeList->begin(); iter!=operationTreeList->end(); iter++)
+ {
+ if( *iter == inputOld )
+ {
+ (*iter) = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ };
+ };
+};
+
+
+
+inline const QtNode::QtNodeType
+QtOperationIterator::getNodeType() const
+{
+ return nodeType;
+}
+
diff --git a/qlparser/qtpointdata.cc b/qlparser/qtpointdata.cc
new file mode 100644
index 0000000..acc1a3d
--- /dev/null
+++ b/qlparser/qtpointdata.cc
@@ -0,0 +1,114 @@
+/*
+* 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, QtPointData: $Id: qtpointdata.cc,v 1.7 2005/09/03 20:17:55 rasdev Exp $";
+
+using namespace std;
+
+using namespace std;
+
+#include "qlparser/qtpointdata.hh"
+#include <cstring>
+// deprecated, not any longer available -- PB 2005-jan-14
+// #include <iostream>
+
+
+QtPointData::QtPointData( const r_Point& point )
+ : pointData(point), QtData()
+{
+}
+
+
+QtPointData::~QtPointData()
+{
+}
+
+
+QtDataType
+QtPointData::getDataType() const
+{
+ return QT_POINT;
+}
+
+
+bool
+QtPointData::equal( const QtData* obj ) const
+{
+ int returnValue = false; // not equal by initialization
+
+ if( obj->getDataType() == QT_POINT )
+ {
+ QtPointData* pt = (QtPointData*)obj;
+
+ // check domains
+ returnValue = (pointData == pt->getPointData());
+ }
+
+ return returnValue;
+}
+
+
+std::string
+QtPointData::getSpelling() const
+{
+ std::string result;
+
+ // buffer
+ int bufferLen = pointData.dimension() * 50; // on the save side for one integers per dimension plus colon and brackets
+ char* buffer = new char[ bufferLen ];
+ // replaced deprecated ostrstream -- PB 2005-jan-14
+ // ostrstream bufferStream( buffer, bufferLen );
+ ostringstream bufferStream( buffer );
+
+ bufferStream << pointData << std::ends;
+
+ result.append( std::string( buffer ) );
+
+ delete[] buffer;
+ buffer=NULL;
+ return result;
+}
+
+
+char* QtPointData::getTypeStructure() const
+{
+ return strdup("point");
+}
+
+
+void
+QtPointData::printStatus( std::ostream& stream ) const
+{
+ stream << "point, value: " << std::flush;
+ stream << pointData << std::flush;
+ QtData::printStatus( stream );
+}
diff --git a/qlparser/qtpointdata.hh b/qlparser/qtpointdata.hh
new file mode 100644
index 0000000..11695f2
--- /dev/null
+++ b/qlparser/qtpointdata.hh
@@ -0,0 +1,101 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#ifndef _QTPOINTDATA_
+#define _QTPOINTDATA_
+
+#include "qlparser/qtdata.hh"
+
+#include "raslib/point.hh"
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+// removed deprecated ostrsteam -- PB 2005-jan-14
+// #include <strstream.h>
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+ The class encapsulates a point of type \Ref{r_Point}.
+*/
+
+class QtPointData : public QtData
+{
+ public:
+ /// constructor getting a point
+ QtPointData( const r_Point& point );
+
+ /// virtual destructor
+ virtual ~QtPointData();
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+
+ ///
+ inline const r_Point& getPointData() const;
+ ///
+ inline void setPointData( const r_Point& point );
+
+ /// returns a null-terminated string describing the type structure
+ virtual char* getTypeStructure() const;
+ /**
+ The string pointer has to be free using free() by the caller.
+ */
+
+ ///
+ //@}
+
+ /// returns {\tt QT_POINT}
+ virtual QtDataType getDataType() const;
+
+ /// compares data content
+ virtual bool equal( const QtData* obj ) const;
+
+ /// returns content dependent string representation
+ virtual std::string getSpelling() const;
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+
+ private:
+ /// attribute storing the minterval
+ r_Point pointData;
+};
+
+#include "qlparser/qtpointdata.icc"
+
+#endif
+
+
+
+
+
diff --git a/qlparser/qtpointdata.icc b/qlparser/qtpointdata.icc
new file mode 100644
index 0000000..d47ce57
--- /dev/null
+++ b/qlparser/qtpointdata.icc
@@ -0,0 +1,45 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const r_Point&
+QtPointData::getPointData() const
+{
+ return pointData;
+}
+
+
+inline void
+QtPointData::setPointData( const r_Point& point )
+{
+ pointData = point;
+}
+
+
+
diff --git a/qlparser/qtpointop.cc b/qlparser/qtpointop.cc
new file mode 100644
index 0000000..2f9f89b
--- /dev/null
+++ b/qlparser/qtpointop.cc
@@ -0,0 +1,214 @@
+/*
+* 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, QtPointOp: $Id: qtpointop.cc,v 1.7 2002/06/05 18:18:17 coman Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtpointop.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtpointdata.hh"
+#include "qlparser/qtatomicdata.hh"
+
+#include "catalogmgr/ops.hh"
+#include "relcatalogif/type.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+
+const QtNode::QtNodeType QtPointOp::nodeType = QT_POINTOP;
+
+QtPointOp::QtPointOp( QtOperationList* opList )
+ : QtNaryOperation( opList )
+{
+}
+
+
+
+QtData*
+QtPointOp::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtPointOp", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtDataList* operandList = NULL;
+
+ if( getOperands( inputList, operandList ) )
+ {
+ vector<QtData*>::iterator dataIter;
+ bool goOn=true;
+
+ if( operandList )
+ {
+ // first check operand types
+ for( dataIter=operandList->begin(); dataIter!=operandList->end() && goOn; dataIter++ )
+ if (!( (*dataIter)->getDataType() == QT_SHORT || (*dataIter)->getDataType() == QT_USHORT ||
+ (*dataIter)->getDataType() == QT_LONG || (*dataIter)->getDataType() == QT_ULONG ||
+ (*dataIter)->getDataType() == QT_OCTET || (*dataIter)->getDataType() == QT_CHAR ))
+ {
+ goOn=false;
+ break;
+ }
+
+ if( !goOn )
+ {
+ RMInit::logOut << "Error: QtPointOp::evaluate() - operands of point expression must be of type integer." << std::endl;
+
+ parseInfo.setErrorNo(410);
+
+ // delete the old operands
+ if( operandList )
+ {
+ for( dataIter=operandList->begin(); dataIter!=operandList->end(); dataIter++ )
+ if( (*dataIter) ) (*dataIter)->deleteRef();
+
+ delete operandList;
+ operandList=NULL;
+ }
+
+ throw parseInfo;
+ }
+
+ //
+ // create a QtPointData object and fill it
+ //
+ r_Point pt( operandList->size() );
+
+ for( dataIter=operandList->begin(); dataIter!=operandList->end(); dataIter++ )
+ if( (*dataIter)->getDataType() == QT_SHORT ||
+ (*dataIter)->getDataType() == QT_LONG ||
+ (*dataIter)->getDataType() == QT_OCTET )
+ pt << ((QtAtomicData*)(*dataIter))->getSignedValue();
+ else
+ pt << ((QtAtomicData*)(*dataIter))->getUnsignedValue();
+
+ returnValue = new QtPointData( pt );
+
+ // delete the old operands
+ if( operandList )
+ {
+ for( dataIter=operandList->begin(); dataIter!=operandList->end(); dataIter++ )
+ if( (*dataIter) ) (*dataIter)->deleteRef();
+
+ delete operandList;
+ operandList=NULL;
+ }
+ }
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtPointOp::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtPointOp Object " << getNodeType() << std::endl;
+
+ QtNaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtPointOp::printAlgebraicExpression( std::ostream& s )
+{
+ s << "[";
+
+ QtNaryOperation::printAlgebraicExpression( s );
+
+ s << "]";
+}
+
+
+
+const QtTypeElement&
+QtPointOp::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtPointOp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ QtOperationList::iterator iter;
+ bool opTypesValid = true;
+
+ for( iter=operationList->begin(); iter!=operationList->end() && opTypesValid; iter++ )
+ {
+ const QtTypeElement& type = (*iter)->checkType( typeTuple );
+
+ // valid types: integers
+ if (!( type.getDataType() == QT_SHORT ||
+ type.getDataType() == QT_LONG ||
+ type.getDataType() == QT_OCTET ||
+ type.getDataType() == QT_USHORT ||
+ type.getDataType() == QT_ULONG ||
+ type.getDataType() == QT_CHAR))
+ {
+ opTypesValid = false;
+ break;
+ }
+ }
+
+ if( !opTypesValid )
+ {
+ RMInit::logOut << "Error: QtPointOp::checkType() - operand of point expression must be of type integer." << std::endl;
+ parseInfo.setErrorNo(410);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_POINT );
+
+ return dataStreamType;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtpointop.hh b/qlparser/qtpointop.hh
new file mode 100644
index 0000000..08f671a
--- /dev/null
+++ b/qlparser/qtpointop.hh
@@ -0,0 +1,81 @@
+#ifndef _QTPOINTOP_
+#define _QTPOINTOP_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtnaryoperation.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represents the root of a point expression.
+
+*/
+
+class QtPointOp : public QtNaryOperation
+{
+ public:
+ /// constructor getting the two operands
+ QtPointOp( QtOperationList* opList );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+#include "qlparser/qtpointop.icc"
+
+#endif
+
diff --git a/qlparser/qtpointop.icc b/qlparser/qtpointop.icc
new file mode 100644
index 0000000..c9b8bf1
--- /dev/null
+++ b/qlparser/qtpointop.icc
@@ -0,0 +1,34 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtPointOp::getNodeType() const
+{
+ return nodeType;
+}
diff --git a/qlparser/qtscalardata.cc b/qlparser/qtscalardata.cc
new file mode 100644
index 0000000..670204d
--- /dev/null
+++ b/qlparser/qtscalardata.cc
@@ -0,0 +1,204 @@
+/*
+* 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, QtScalarData: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtscalardata.cc,v 1.17 2005/07/06 22:48:34 rasdev Exp $";
+
+#include "qlparser/qtscalardata.hh"
+
+#include "relcatalogif/basetype.hh"
+
+#include "raslib/rmdebug.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#include <cstring>
+#include <cstdlib>
+using namespace std;
+#endif
+
+#include <iostream>
+
+// deprecated, not available any longer -- PB 2005-jan-14
+// #include <strstream.h>
+
+QtScalarData::QtScalarData()
+ : valueBuffer(NULL),
+ valueType(NULL)
+{
+}
+
+
+
+QtScalarData::QtScalarData( const QtScalarData& obj )
+ : QtData( obj )
+{
+ setLifetime( obj.getLifetime() );
+
+ // Pointer received from TypeFactory just can be copied.
+ valueType = obj.valueType;
+
+ if( valueType && obj.valueBuffer )
+ {
+ valueBuffer = new char[ valueType->getSize() ];
+ memcpy( (void*)valueBuffer, (void*)obj.valueBuffer, valueType->getSize() );
+ }
+ else
+ valueBuffer = NULL;
+}
+
+
+
+QtScalarData::~QtScalarData()
+{
+ // valueType is not deleted because it is maintained by the typeFactory
+
+ if( valueBuffer )
+ {
+ delete[] valueBuffer;
+ valueBuffer=NULL;
+ }
+}
+
+
+
+QtDataType
+QtScalarData::getDataType() const
+{
+ QtDataType returnValue = QT_BOOL;
+
+ if( valueType )
+ switch( valueType->getType() )
+ {
+ case BOOLTYPE: returnValue = QT_BOOL; break;
+ case CHAR: returnValue = QT_CHAR; break;
+ case OCTET: returnValue = QT_OCTET; break;
+ case USHORT: returnValue = QT_USHORT; break;
+ case SHORT: returnValue = QT_SHORT; break;
+ case ULONG: returnValue = QT_ULONG; break;
+ case LONG: returnValue = QT_LONG; break;
+ case FLOAT: returnValue = QT_FLOAT; break;
+ case DOUBLE: returnValue = QT_DOUBLE; break;
+ case STRUCT: returnValue = QT_COMPLEX; break;
+ default:
+ RMDBGONCE(0, RMDebug::module_qlparser, "r_QtScalarData", "getDataType() bad type " << valueType->getType());
+ break;
+ }
+
+ return returnValue;
+}
+
+
+
+bool
+QtScalarData::isScalarData() const
+{
+ return true;
+}
+
+
+bool
+QtScalarData::equal( const QtData* obj ) const
+{
+ int returnValue = false; // not equal by initialization
+
+ if( obj->isScalarData() )
+ {
+ QtScalarData* scalarObj = (QtScalarData*)obj;
+
+ if( getDataType() == scalarObj->getDataType() ) // Attention: this is not correct for structs
+ // compare value buffers
+ returnValue = (memcmp( (void*)valueBuffer, (void*)scalarObj->valueBuffer, valueType->getSize() ) == 0);
+
+ }
+
+ return returnValue;
+}
+
+
+
+string
+QtScalarData::getSpelling() const
+{
+ string result;
+
+ // buffer for hex representation of chars
+ int bufferLen = valueType->getSize() * 2 + 1 + 2; // added final "+2" to remove memleak -- PB 2006-aug-17
+ char* buffer = new char[ bufferLen ];
+ // replaced deprecated ostrstream -- PB 2005-jan-14
+ // ostrstream bufferStream( buffer, bufferLen );
+ ostringstream bufferStream( buffer );
+
+ for( int i=0; i<valueType->getSize(); i++ )
+ bufferStream << hex << valueBuffer[i];
+
+ bufferStream << ends;
+
+ result.append( string( buffer ) );
+
+ delete[] buffer;
+ buffer = NULL;
+ return result;
+}
+
+
+char* QtScalarData::getTypeStructure() const
+{
+ if( valueType )
+ return valueType->getTypeStructure();
+ else
+ return NULL;
+}
+
+
+void
+QtScalarData::printStatus( ostream& stream ) const
+{
+ if( valueType )
+ {
+ char* typeStructure = valueType->getTypeStructure();
+
+ stream << "type: " << flush << valueType->getTypeName()
+ << ", structure: " << flush << typeStructure
+ << ", value: " << flush;
+
+ valueType->printCell( stream, valueBuffer );
+
+ free( typeStructure );
+ typeStructure=NULL;
+ QtData::printStatus( stream );
+ }
+ else
+ stream << "<no type>";
+}
diff --git a/qlparser/qtscalardata.hh b/qlparser/qtscalardata.hh
new file mode 100644
index 0000000..9ef33cb
--- /dev/null
+++ b/qlparser/qtscalardata.hh
@@ -0,0 +1,137 @@
+#ifndef _QTSCALARDATA_HH_
+#define _QTSCALARDATA_HH_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtdata.hh"
+#include "catalogmgr/typefactory.hh"
+
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The abstract class represents a scalar data handled by the
+ query tree. It can either be atomic (\Ref{QtAtomicData})
+ or complex (\Ref{QtComplexData}).
+
+*/
+
+class QtScalarData : public QtData
+{
+ public:
+ /// default constructor
+ QtScalarData();
+
+ /// copy constructor
+ QtScalarData( const QtScalarData& obj );
+
+ /// virtual destructor
+ virtual ~QtScalarData();
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+
+ /// returns data type
+ virtual QtDataType getDataType() const;
+
+ /// returns true meaning that the data is of type scalar
+ virtual bool isScalarData() const;
+
+ /// returns a pointer to the value type
+ inline const BaseType* getValueType() const;
+
+ /// sets the value type
+ inline void setValueType( const BaseType* newType );
+
+ /// returns a pointer to the internal character representation
+ inline const char* getValueBuffer() const;
+
+ /// sets the value buffer
+ inline void setValueBuffer( char* buffer );
+
+ /// returns a null-terminated string describing the type structure
+ virtual char* getTypeStructure() const;
+ /**
+ The string pointer has to be free using free() by the caller.
+ */
+
+ ///
+ //@}
+
+ /// compares data content
+ virtual bool equal( const QtData* obj ) const;
+
+ /// returns content dependent string representation
+ virtual std::string getSpelling() const;
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+
+ protected:
+ /// pointer to the value type
+ const BaseType* valueType;
+
+ /// pointer to the value buffer
+ char* valueBuffer;
+};
+
+#include "qlparser/qtscalardata.icc"
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qlparser/qtscalardata.icc b/qlparser/qtscalardata.icc
new file mode 100644
index 0000000..873f0b7
--- /dev/null
+++ b/qlparser/qtscalardata.icc
@@ -0,0 +1,58 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const BaseType*
+QtScalarData::getValueType() const
+{
+ return valueType;
+}
+
+
+
+inline void
+QtScalarData::setValueType( const BaseType* newType )
+{
+ valueType = newType;
+}
+
+
+
+inline const char*
+QtScalarData::getValueBuffer() const
+{
+ return valueBuffer;
+}
+
+
+
+inline void
+QtScalarData::setValueBuffer( char* buffer )
+{
+ valueBuffer = buffer;
+}
diff --git a/qlparser/qtselectioniterator.cc b/qlparser/qtselectioniterator.cc
new file mode 100644
index 0000000..f6d2529
--- /dev/null
+++ b/qlparser/qtselectioniterator.cc
@@ -0,0 +1,281 @@
+/*
+* 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, QtSelectionIterator: $Id: qtselectioniterator.cc,v 1.24 2001/08/07 12:00:12 barbat Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtselectioniterator.hh"
+#include "qlparser/qtatomicdata.hh"
+
+#include "relcatalogif/type.hh"
+
+#include <iostream>
+#include <string>
+#include <vector>
+using namespace std;
+
+const QtNode::QtNodeType QtSelectionIterator::nodeType = QtNode::QT_SELECTION_ITERATOR;
+
+
+QtSelectionIterator::QtSelectionIterator()
+ : QtIterator(),
+ conditionTree(NULL)
+{
+}
+
+
+QtSelectionIterator::QtSelectionIterator( QtNode* node )
+ : QtIterator( node ),
+ conditionTree(NULL)
+{
+}
+
+
+QtSelectionIterator::~QtSelectionIterator()
+{
+ if( conditionTree )
+ {
+ delete conditionTree;
+ conditionTree=NULL;
+ }
+}
+
+
+QtNode::QtNodeList*
+QtSelectionIterator::getChilds( QtChildType flag )
+{
+ QtNodeList* resultList=NULL;
+ QtNodeList* subList=NULL;
+
+ RMDBGENTER( 1, RMDebug::module_qlparser, "QtSelectionIterator", " QtSelectionIterator::getChilds() ")
+
+ resultList = QtIterator::getChilds( flag );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator", \
+ RMInit::dbgOut << "1. childs from stream subtree " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+ if( conditionTree )
+ {
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ {
+ subList = conditionTree->getChilds( flag );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator", \
+ RMInit::dbgOut << "2. childs from operation subtree (without direct childs) " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=subList->begin(); debugIter!=subList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator", \
+ RMInit::dbgOut << "3. merge of the lists " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator", \
+ RMInit::dbgOut << "4. old list (must be empty)" << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=subList->begin(); debugIter!=subList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ };
+
+ // add nodes of next level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( conditionTree );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator",
+ RMInit::dbgOut << "4. current child list including direct childs " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+ };
+
+ return resultList;
+}
+
+
+void
+QtSelectionIterator::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtSelectionIterator Object: type " << flush;
+ dataStreamType.printStatus( s );
+ s << endl;
+
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ {
+ if( conditionTree )
+ {
+ s << SPACE_STR(tab).c_str() << "condition : " << endl;
+ conditionTree->printTree( tab + 2, s );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no condition" << endl;
+ }
+
+ QtIterator::printTree( tab, s, mode );
+}
+
+
+
+void
+QtSelectionIterator::printAlgebraicExpression( ostream& s )
+{
+ s << "sel<";
+
+ conditionTree->printAlgebraicExpression( s );
+
+ s << ">";
+
+ QtIterator::printAlgebraicExpression( s );
+}
+
+
+
+QtNode::QtDataList*
+QtSelectionIterator::next()
+{
+ RMDBGENTER( 1, RMDebug::module_qlparser, "QtSelectionIterator", "QtSelectionIterator::next()" )
+
+ QtDataList* returnValue = NULL;
+
+ if( inputs )
+ {
+ bool nextTupelValid = false;
+ QtDataList* actualTupel=NULL;
+
+ while( !nextTupelValid )
+ {
+ actualTupel = (*inputs)[0]->next();
+
+ if( actualTupel )
+ {
+ if( conditionTree )
+ {
+ // evaluate the condition tree
+ QtData* resultData = conditionTree->evaluate( actualTupel );
+
+ if( resultData )
+ {
+ if( resultData->getDataType() == QT_BOOL )
+ nextTupelValid = (bool)((QtAtomicData*)resultData)->getUnsignedValue();
+ else
+ {
+ RMInit::logOut << "Error: QtSelectionIterator::next() - result of the WHERE part must be of type Bool." << endl;
+ parseInfo.setErrorNo(359);
+ throw parseInfo;
+ }
+
+ resultData->deleteRef();
+
+ if( !nextTupelValid )
+ {
+ // delete transient objects
+ vector<QtData*>::iterator iter;
+
+ for( iter=actualTupel->begin(); iter!=actualTupel->end(); iter++)
+ if( *iter ) (*iter)->deleteRef();
+
+ // delete vector itself
+ delete actualTupel;
+ actualTupel = NULL;
+ };
+ }
+ }
+ else
+ nextTupelValid = true;
+ }
+ else
+ break;
+ }
+
+ returnValue = actualTupel;
+ }
+
+ RMDBGEXIT( 1, RMDebug::module_qlparser, "QtSelectionIterator", "QtSelectionIterator::next()" )
+
+ return returnValue;
+}
+
+/*
+inline void
+QtSelectionIterator::preOptimize()
+{
+ if( conditionTree )
+ conditionTree->optimizeLoad( new QtNode::QtTrimList );
+
+ // pass it to the input streams
+ QtIterator::preOptimize();
+};
+*/
+
+const QtTypeTuple&
+QtSelectionIterator::checkType()
+{
+ RMDBCLASS( "QtSelectionIterator", "checkType()", "qlparser", __FILE__, __LINE__ )
+
+ // concatenate types of inputs
+ getInputTypeTuple( dataStreamType );
+
+ // type check for condition tree
+ if( conditionTree )
+ {
+ const QtTypeElement& type = conditionTree->checkType( (QtTypeTuple*)&dataStreamType );
+
+ if( type.getDataType() != QT_BOOL )
+ {
+ RMInit::logOut << "Error: QtSelectionIterator::next() - result of the WHERE part must be of type Bool." << endl;
+ parseInfo.setErrorNo(359);
+ throw parseInfo;
+ }
+ }
+
+ // pass type tuple
+ return dataStreamType;
+}
diff --git a/qlparser/qtselectioniterator.hh b/qlparser/qtselectioniterator.hh
new file mode 100644
index 0000000..d187e68
--- /dev/null
+++ b/qlparser/qtselectioniterator.hh
@@ -0,0 +1,119 @@
+#ifndef _QTSELECTIONITERATOR_
+#define _QTSELECTIONITERATOR_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtiterator.hh"
+#include "qlparser/qtoperation.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+An condition expression specified through a reference to
+an instance of the QtOperation sub-hierarchy, is evaluated for the actual input
+The boolean result determines if the tupel is passed to the output stream or not.
+So the method {\tt next()} reads tupels from its inputs until one can be
+passed to its caller. The class represents the WHERE condition in the query
+
+*/
+
+class QtSelectionIterator : public QtIterator
+{
+ public:
+ /// default constructor
+ QtSelectionIterator();
+
+ /// constructor getting a pointer to the parent
+ QtSelectionIterator( QtNode* node );
+
+ /// virtual destructor
+ virtual ~QtSelectionIterator();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// method for query rewrite
+ inline virtual void setInput( QtOperation* child, QtOperation* input);
+
+ /// optimizing load access
+// virtual void preOptimize();
+ /**
+ Trigger load optimization in the condition tree and pass the optimization step to
+ the input streams.
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: Operations of the ONC protocol:
+ //@{
+ ///
+ QtDataList* next();
+ //@}
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ //inline virtual void setParents();
+ ///
+ inline void setConditionTree( QtOperation* operation );
+ ///
+ inline QtOperation* getConditionTree();
+ //@}
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking
+ virtual const QtTypeTuple& checkType();
+
+ private:
+ /// pointer to a tree representing the where part of the query
+ QtOperation* conditionTree;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtselectioniterator.icc"
+
+#endif
+
+
diff --git a/qlparser/qtselectioniterator.icc b/qlparser/qtselectioniterator.icc
new file mode 100644
index 0000000..5947f9c
--- /dev/null
+++ b/qlparser/qtselectioniterator.icc
@@ -0,0 +1,68 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline void
+QtSelectionIterator::setConditionTree( QtOperation* operation )
+{
+ conditionTree = operation;
+
+ if( operation )
+ operation->setParent( this );
+};
+
+
+
+inline QtOperation*
+QtSelectionIterator::getConditionTree()
+{
+ return( conditionTree );
+};
+
+
+
+inline void
+QtSelectionIterator::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ if( conditionTree == inputOld )
+ {
+ setConditionTree( inputNew );
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+};
+
+
+
+inline const QtNode::QtNodeType
+QtSelectionIterator::getNodeType() const
+{
+ return nodeType;
+}
+
diff --git a/qlparser/qtstringdata.cc b/qlparser/qtstringdata.cc
new file mode 100644
index 0000000..41abcfa
--- /dev/null
+++ b/qlparser/qtstringdata.cc
@@ -0,0 +1,88 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, QtStringData: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtstringdata.cc,v 1.8 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtstringdata.hh"
+
+#include <iostream>
+#include <cstring>
+
+
+
+QtStringData::QtStringData( const std::string& str )
+ : stringData(str), QtData()
+{
+}
+
+
+
+QtDataType
+QtStringData::getDataType() const
+{
+ return QT_STRING;
+}
+
+
+
+bool
+QtStringData::equal( const QtData* obj ) const
+{
+ bool returnValue = false; // not equal by initialization
+
+ if( obj->getDataType() == QT_STRING )
+ returnValue = (stringData == ((QtStringData*)obj)->getStringData());
+
+ return returnValue;
+}
+
+
+
+std::string
+QtStringData::getSpelling() const
+{
+ return stringData;
+}
+
+
+
+char* QtStringData::getTypeStructure() const
+{
+ return strdup("string");
+}
+
+
+
+void
+QtStringData::printStatus( std::ostream& stream ) const
+{
+ stream << "string, value: " << stringData.c_str() << std::flush;
+
+ QtData::printStatus( stream );
+}
diff --git a/qlparser/qtstringdata.hh b/qlparser/qtstringdata.hh
new file mode 100644
index 0000000..837ac05
--- /dev/null
+++ b/qlparser/qtstringdata.hh
@@ -0,0 +1,97 @@
+#ifndef _QTSTRINGDATA_
+#define _QTSTRINGDATA_
+
+#include "qlparser/qtdata.hh"
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+ The class encapsulates a string.
+*/
+
+class QtStringData : public QtData
+{
+ public:
+ /// constructor getting the string
+ QtStringData( const std::string& str );
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+
+ ///
+ inline const std::string& getStringData() const;
+ ///
+ inline void setStringData( const std::string& str );
+
+ /// returns a null-terminated string describing the type structure
+ virtual char* getTypeStructure() const;
+ /**
+ The string pointer has to be free using free() by the caller.
+ */
+
+ ///
+ //@}
+
+ /// returns {\tt QT_STRING}
+ virtual QtDataType getDataType() const;
+
+ /// compares data content
+ virtual bool equal( const QtData* obj ) const;
+
+ /// returns content dependent string representation
+ virtual std::string getSpelling() const;
+
+ /// print status of the object to the specified stream
+ virtual void printStatus( std::ostream& stream = std::cout ) const;
+
+ private:
+ /// prevents from using the default constructor
+ QtStringData(){};
+
+ ///
+ std::string stringData;
+};
+
+#include "qlparser/qtstringdata.icc"
+
+#endif
+
+
+
+
diff --git a/qlparser/qtstringdata.icc b/qlparser/qtstringdata.icc
new file mode 100644
index 0000000..eea6747
--- /dev/null
+++ b/qlparser/qtstringdata.icc
@@ -0,0 +1,42 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const std::string&
+QtStringData::getStringData() const
+{
+ return stringData;
+}
+
+
+inline void
+QtStringData::setStringData( const std::string& str )
+{
+ stringData = str;
+}
diff --git a/qlparser/qtunaryfunc.cc b/qlparser/qtunaryfunc.cc
new file mode 100644
index 0000000..fa151fd
--- /dev/null
+++ b/qlparser/qtunaryfunc.cc
@@ -0,0 +1,414 @@
+/*
+* 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, QtIntervalLoOp, QtIntervalHiOp, QtSDom: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtunaryfunc.cc,v 1.11 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtunaryfunc.hh"
+#include "qlparser/qtintervaldata.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtmintervaldata.hh"
+#include "qlparser/qtmdd.hh"
+
+const QtNode::QtNodeType QtIntervalLoOp::nodeType = QtNode::QT_LO;
+
+
+QtIntervalLoOp::QtIntervalLoOp( QtOperation* newInput )
+ : QtUnaryOperation( newInput )
+{
+}
+
+
+
+QtData*
+QtIntervalLoOp::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtIntervalLoOp", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ operand = input->evaluate( inputList );
+
+ if( operand )
+ {
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_INTERVAL )
+ {
+ RMInit::logOut << "Internal error in QtIntervalLoOp::evaluate() - "
+ << "runtime type checking failed (INTERVAL)." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ return 0;
+ }
+#endif
+
+ QtIntervalData* intervalData = (QtIntervalData*)operand;
+
+ r_Sinterval sinterval = intervalData->getIntervalData();
+
+ if( sinterval.is_low_fixed() )
+ {
+ returnValue = new QtAtomicData( (r_Long)(sinterval.low()), 4 );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtIntervalLoOp::evaluate() - operation lo() can not be used for an open bound." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ parseInfo.setErrorNo(394);
+ throw parseInfo;
+ }
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ }
+ else
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtIntervalLoOp", "Information: QtIntervalLoOp::evaluate() - operand is not provided." )
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtIntervalLoOp::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtIntervalLoOp Object: " << std::endl;
+
+ QtUnaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtIntervalLoOp::printAlgebraicExpression( std::ostream& s )
+{
+ s << "(" << std::flush;
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ").lo ";
+}
+
+
+
+const QtTypeElement&
+QtIntervalLoOp::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtIntervalLoOp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input type
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ if( inputType.getDataType() != QT_INTERVAL )
+ {
+ RMInit::logOut << "Error: QtIntervalLoOp::checkType() - operation lo() must be of type interval." << std::endl;
+ parseInfo.setErrorNo(393);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_LONG );
+ }
+ else
+ RMInit::logOut << "Error: QtIntervalLoOp::checkType() - operand branch invalid." << std::endl;
+
+ return dataStreamType;
+}
+
+
+
+const QtNode::QtNodeType QtIntervalHiOp::nodeType = QtNode::QT_HI;
+
+
+QtIntervalHiOp::QtIntervalHiOp( QtOperation* newInput )
+ : QtUnaryOperation( newInput )
+{
+}
+
+
+
+QtData*
+QtIntervalHiOp::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtIntervalHiOp", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ operand = input->evaluate( inputList );
+
+ if( operand )
+ {
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_INTERVAL )
+ {
+ RMInit::logOut << "Internal error in QtIntervalHiOp::evaluate() - "
+ << "runtime type checking failed (INTERVAL)." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ return 0;
+ }
+#endif
+
+ QtIntervalData* intervalData = (QtIntervalData*)operand;
+
+ r_Sinterval sinterval = intervalData->getIntervalData();
+
+ if( sinterval.is_high_fixed() )
+ {
+ returnValue = new QtAtomicData( (r_Long)(sinterval.high()), 4 );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtIntervalHiOp::evaluate() - operation lo() can not be used for an open bound." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ parseInfo.setErrorNo(394);
+ throw parseInfo;
+ }
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+ else
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtIntervalHiOp", "Information: QtIntervalHiOp::evaluate() - operand is not provided." )
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtIntervalHiOp::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtIntervalHiOp Object: " << std::endl;
+
+ QtUnaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtIntervalHiOp::printAlgebraicExpression( std::ostream& s )
+{
+ s << "(" << std::flush;
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ").hi ";
+}
+
+
+
+const QtTypeElement&
+QtIntervalHiOp::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtIntervalHiOp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input type
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ if( inputType.getDataType() != QT_INTERVAL )
+ {
+ RMInit::logOut << "Error: QtIntervalHiOp::checkType() - operation lo() must be of type interval." << std::endl;
+ parseInfo.setErrorNo(393);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_LONG );
+ }
+ else
+ RMInit::logOut << "Error: QtIntervalHiOp::checkType() - operand branch invalid." << std::endl;
+ return dataStreamType;
+}
+
+
+
+
+const QtNode::QtNodeType QtSDom::nodeType = QtNode::QT_SDOM;
+
+
+QtSDom::QtSDom( QtOperation* newInput )
+ : QtUnaryOperation( newInput )
+{
+}
+
+
+
+QtData*
+QtSDom::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtSDom", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ operand = input->evaluate( inputList );
+
+ if( operand )
+ {
+#ifdef QT_RUNTIME_TYPE_CHECK
+ if( operand->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Internal error in QtSDom::evaluate() - "
+ << "runtime type checking failed (MDD)." << std::endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ return 0;
+ }
+#endif
+
+ QtMDD* qtMDD = (QtMDD*) operand;
+
+ returnValue = new QtMintervalData( qtMDD->getLoadDomain() );
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+ else
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtSDom", "Information: QtSDom::evaluate() - operand is not provided." )
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtSDom::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtSDom", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ // reset trimList because optimization enters a new MDD area
+
+ // delete list
+ vector<QtNode::QtTrimElement*>::iterator iter;
+ for( iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+ delete trimList;
+ trimList=NULL;
+
+ if( input )
+ input->optimizeLoad( new QtNode::QtTrimList );
+}
+
+
+
+void
+QtSDom::printTree( int tab, std::ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtSDom Object: " << std::endl;
+
+ QtUnaryOperation::printTree( tab, s, mode );
+}
+
+
+
+void
+QtSDom::printAlgebraicExpression( std::ostream& s )
+{
+ s << "sdom(" << std::flush;
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtTypeElement&
+QtSDom::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtSDom", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input type
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ if( inputType.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtSDom::checkType() - operand must be of type MDD." << std::endl;
+ parseInfo.setErrorNo(395);
+ throw parseInfo;
+ }
+
+ dataStreamType.setDataType( QT_MINTERVAL );
+ }
+ else
+ RMInit::logOut << "Error: QtSDom::checkType() - operand branch invalid." << std::endl;
+
+ return dataStreamType;
+}
+
+
diff --git a/qlparser/qtunaryfunc.hh b/qlparser/qtunaryfunc.hh
new file mode 100644
index 0000000..b78ea35
--- /dev/null
+++ b/qlparser/qtunaryfunc.hh
@@ -0,0 +1,161 @@
+#ifndef _QTUNARYFUNC_HH__
+#define _QTUNARYFUNC_HH___
+
+#include "qlparser/qtunaryoperation.hh"
+
+// forward declarations
+class QtOperation;
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represenst a function returning the lower bound of an interval.
+
+*/
+
+class QtIntervalLoOp : public QtUnaryOperation
+{
+ public:
+ /// constructor getting operand
+ QtIntervalLoOp( QtOperation* newInput );
+
+ /// evaluates the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represenst a function returning the higher bound of an interval.
+
+*/
+
+class QtIntervalHiOp : public QtUnaryOperation
+{
+ public:
+ /// constructor getting operand
+ QtIntervalHiOp( QtOperation* newInput );
+
+ /// evaluates the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class represenst a function returning the spatial domain of an mdd object.
+
+*/
+
+class QtSDom : public QtUnaryOperation
+{
+ public:
+ /// constructor getting operand
+ QtSDom( QtOperation* newInput );
+
+ /// evaluates the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+ /**
+ The method deletes the given {\tt trimList} and passes the {\tt optimizeLoad}
+ message with empty triming list to its operand tree.
+
+ Optimization process enters a new MDD area.
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+#include "qlparser/qtunaryfunc.icc"
+
+#endif
+
diff --git a/qlparser/qtunaryfunc.icc b/qlparser/qtunaryfunc.icc
new file mode 100644
index 0000000..c6cccf1
--- /dev/null
+++ b/qlparser/qtunaryfunc.icc
@@ -0,0 +1,51 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const QtNode::QtNodeType
+QtIntervalLoOp::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtIntervalHiOp::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const QtNode::QtNodeType
+QtSDom::getNodeType() const
+{
+ return nodeType;
+}
+
+
diff --git a/qlparser/qtunaryinduce.cc b/qlparser/qtunaryinduce.cc
new file mode 100644
index 0000000..60322d1
--- /dev/null
+++ b/qlparser/qtunaryinduce.cc
@@ -0,0 +1,1013 @@
+/*
+* 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, QtUnaryInduce: $Id: qtunaryinduce.cc,v 1.47 2002/08/19 11:13:27 coman Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtunaryinduce.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtcomplexdata.hh"
+#include "qlparser/qtnode.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "tilemgr/tile.hh"
+
+#include "catalogmgr/typefactory.hh"
+#include "relcatalogif/structtype.hh"
+
+#include <sstream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+const QtNode::QtNodeType QtUnaryInduce::nodeType = QtNode::QT_UNARY_INDUCE;
+
+QtUnaryInduce::QtUnaryInduce( QtOperation* initInput )
+ : QtUnaryOperation( initInput )
+{
+}
+
+
+
+bool
+QtUnaryInduce::getOperand( QtDataList* inputList, QtData* &operand )
+{
+ bool success = false;
+
+ // get the operands
+ operand = input->evaluate( inputList );
+
+ // Test, if the operands are valid.
+ if( operand )
+ success = true;
+ else
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtUnaryInduce", "Information: QtUnaryInduce::getOperand() - operand is not provided." )
+ }
+
+ return success;
+}
+
+
+
+QtData*
+QtUnaryInduce::computeOp( QtData* operand, Ops::OpType operation )
+{
+ QtData* returnValue = NULL;
+
+ if( operand->getDataType() == QT_MDD )
+ {
+ QtMDD* mdd = (QtMDD*) operand;
+
+ const BaseType* resultCellType = (BaseType*)(Ops::getResultType( operation, mdd->getCellType() ));
+
+ returnValue = computeUnaryMDDOp( mdd, resultCellType, operation);
+ }
+ else if( operand->isScalarData() )
+ {
+ QtScalarData* scalar = (QtScalarData*) operand;
+
+ const BaseType* resultCellType = (BaseType*)(Ops::getResultType( operation, scalar->getValueType() ));
+
+ returnValue = computeUnaryOp( scalar, resultCellType, operation );
+ }
+
+ return returnValue;
+}
+
+
+
+QtData*
+QtUnaryInduce::computeUnaryMDDOp( QtMDD* operand, const BaseType* resultBaseType,
+ Ops::OpType operation, unsigned int operandOffset )
+{
+ RMDBCLASS( "QtUnaryInduce", "computeUnaryMDDOp( QtMDD*, BaseType*, Ops::OpType, unsigned int ) ", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+
+ // get the MDD object
+ MDDObj* op = ((QtMDD*)operand)->getMDDObject();
+
+ // get the area, where the operation has to be applied
+ const r_Minterval &areaOp = ((QtMDD*)operand)->getLoadDomain();
+
+ // contains all tiles of the operand
+ vector<Tile*>* allTiles=NULL;
+
+ // iterator for tiles
+
+ // create MDDObj for result
+ MDDBaseType* mddBaseType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( mddBaseType );
+
+ MDDObj* mddres = new MDDObj( mddBaseType, areaOp );
+
+ // get all tiles in relevant area
+ allTiles = op->intersect(areaOp);
+ std::vector<Tile*>::iterator tileIt = allTiles->begin();
+ if (tileIt != allTiles->end())
+ {
+ Tile* resTile = NULL;
+ UnaryOp* myOp = NULL;
+ if (operation == Ops::OP_IDENTITY)
+ {
+ myOp = Ops::getUnaryOp(operation, resultBaseType, resultBaseType, 0, operandOffset);
+ }
+ else {
+ myOp = Ops::getUnaryOp(operation, resultBaseType, (*tileIt)->getType(), 0, 0);
+ }
+ if (myOp == NULL)
+ {
+ RMInit::logOut << "QtUnaryInduce::computeUnaryMDDOp(...) could not get operation for result type " << resultBaseType->getName() << " argument type " << (*tileIt)->getType() << " operation " << operation << endl;
+ delete myOp;
+ myOp = NULL;
+ delete allTiles;
+ allTiles = NULL;
+ //contents of allTiles are deleted when index is deleted
+ delete mddres;
+ mddres = NULL;
+ delete resTile;
+ resTile = NULL;
+ delete mddres;
+ mddres = NULL;
+ // i am not sure about that error number...
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ // and iterate over them
+ try {
+ for( ; tileIt != allTiles->end(); tileIt++ )
+ {
+ // domain of the actual tile
+ const r_Minterval &tileDom = (*tileIt)->getDomain();
+
+ // domain of the relevant area of the actual tile
+ r_Minterval intersectDom( tileDom.create_intersection( areaOp ) );
+
+ // create tile for result
+ resTile = new Tile( intersectDom, resultBaseType );
+
+ // carry out operation on the relevant area of the tiles
+ resTile->execUnaryOp(myOp, intersectDom, (*tileIt), intersectDom);
+ // insert Tile in result mdd
+ mddres->insertTile( resTile );
+ }
+ }
+ catch(r_Error& err)
+ {
+ RMInit::logOut << "QtUnaryInduce::computeUnaryMDDOp caught " << err.get_errorno() << " " << err.what() << endl;
+ delete myOp;
+ myOp = NULL;
+ delete allTiles;
+ allTiles = NULL;
+ //contents of allTiles are deleted when index is deleted
+ delete mddres;
+ mddres = NULL;
+ delete resTile;
+ resTile = NULL;
+ delete mddres;
+ mddres = NULL;
+ parseInfo.setErrorNo(err.get_errorno());
+ throw parseInfo;
+ }
+ catch (int err)
+ {
+ RMInit::logOut << "QtUnaryInduce::computeUnaryMDDOp caught errno error (" << err << ") in unaryinduce" << endl;
+ delete myOp;
+ myOp = NULL;
+ delete allTiles;
+ allTiles = NULL;
+ //contents of allTiles are deleted when index is deleted
+ delete mddres;
+ mddres = NULL;
+ delete resTile;
+ resTile = NULL;
+ delete mddres;
+ mddres = NULL;
+ parseInfo.setErrorNo(err);
+ throw parseInfo;
+ }
+
+ delete myOp;
+ myOp = NULL;
+ }
+ // delete tile vector
+ delete allTiles;
+ allTiles = NULL;
+
+ // create a new QtMDD object as carrier object for the transient MDD object
+ returnValue = new QtMDD( (MDDObj*)mddres );
+
+ // The following is now done when deleting the last reference to the operand
+ // delete the obsolete MDD object
+ // delete op;
+
+ return returnValue;
+}
+
+
+QtData*
+QtUnaryInduce::computeUnaryOp( QtScalarData* operand, const BaseType* resultBaseType,
+ Ops::OpType operation, unsigned int operandOffset )
+{
+ RMDBCLASS( "QtUnaryInduce", "computeUnaryOp( QtScalarData*, BaseType*, Ops::OpType, unsigned int ) ", "qlparser", __FILE__, __LINE__ )
+
+ QtScalarData* scalarDataObj = NULL;
+
+ // allocate memory for the result
+ char* resultBuffer = new char[ resultBaseType->getSize() ];
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtUnaryInduce", \
+ RMInit::dbgOut << "Operand value "; \
+ operand->getValueType()->printCell( RMInit::dbgOut, operand->getValueBuffer() ); \
+ RMInit::dbgOut << endl; \
+ )
+
+ if(( operation == Ops::OP_IDENTITY )) // || ( operation == Ops::OP_SQRT ))
+ // operand type is the same as result type
+ Ops::execUnaryConstOp( operation, resultBaseType,
+ resultBaseType,
+ resultBuffer,
+ operand->getValueBuffer(),
+ 0, operandOffset );
+ else
+ try
+ {
+ Ops::execUnaryConstOp( operation, resultBaseType,
+ operand->getValueType(),
+ resultBuffer,
+ operand->getValueBuffer(),
+ 0, operandOffset );
+ }
+ catch(int err)
+ {
+ delete[] resultBuffer;
+ resultBuffer = NULL;
+ parseInfo.setErrorNo(err);
+ throw parseInfo;
+ }
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtUnaryInduce", \
+ RMInit::dbgOut << "Result value "; \
+ resultBaseType->printCell( RMInit::dbgOut, resultBuffer ); \
+ RMInit::dbgOut << endl; \
+ )
+
+ if( resultBaseType->getType() == STRUCT )
+ scalarDataObj = new QtComplexData();
+ else
+ scalarDataObj = new QtAtomicData();
+
+ scalarDataObj->setValueType ( resultBaseType );
+ scalarDataObj->setValueBuffer( resultBuffer );
+
+ return scalarDataObj;
+}
+
+
+const QtNode::QtNodeType QtNot::nodeType = QtNode::QT_NOT;
+
+QtNot::QtNot( QtOperation* initInput )
+ : QtUnaryInduce( initInput )
+{
+}
+
+
+QtData*
+QtNot::evaluate( QtDataList* inputList )
+{
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if( getOperand( inputList, operand ) )
+ {
+ returnValue = computeOp( operand, Ops::OP_NOT );
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+ return returnValue;
+}
+
+
+
+void
+QtNot::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtNot Object" << endl;
+
+ QtUnaryInduce::printTree( tab+2, s, mode );
+}
+
+
+
+void
+QtNot::printAlgebraicExpression( ostream& s )
+{
+ s << "not(";
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ")";
+}
+
+
+
+const QtTypeElement&
+QtNot::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtNot", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtNot", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+
+ if( inputType.getDataType() == QT_MDD )
+ {
+ const BaseType* baseType = ((const MDDBaseType*)(inputType.getType()))->getBaseType();
+
+ const BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_NOT, baseType ));
+
+ if( !resultBaseType )
+ {
+ RMInit::logOut << "Error: QtNot::checkType() - induce operand type is not supported." << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+
+ dataStreamType.setType( resultMDDType );
+ }
+ else if( inputType.isBaseType() )
+ {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+
+ const BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_NOT, baseType ));
+
+ if( !resultBaseType )
+ {
+ RMInit::logOut << "Error: QtNot::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+
+ // MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ // TypeFactory::addTempType( resultMDDType );
+
+ // dataStreamType.setType( resultMDDType );
+ dataStreamType.setType( resultBaseType );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtNot::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtNot::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
+
+
+const QtNode::QtNodeType QtDot::nodeType = QtNode::QT_DOT;
+
+
+
+QtDot::QtDot( const string& initElementName )
+ : QtUnaryInduce( NULL ),
+ elementName( initElementName ),
+ elementNo(-1)
+{
+}
+
+
+
+QtDot::QtDot( unsigned initElementNo )
+ : QtUnaryInduce( NULL ),
+ elementNo( initElementNo )
+{
+}
+
+
+
+bool
+QtDot::equalMeaning( QtNode* node )
+{
+ bool result = false;
+
+ if( nodeType == node->getNodeType() )
+ {
+ QtDot* dotNode = (QtDot* ) node; // by force
+
+ // In future, elementName have to be converted to elementNo
+ // and then just the numbers are compared.
+ if( (elementNo != -1 && elementNo == dotNode->elementNo) ||
+ (elementNo == -1 && elementName == dotNode->elementName) )
+ result = input->equalMeaning( dotNode->getInput() );
+ };
+
+ return result;
+}
+
+
+string
+QtDot::getSpelling()
+{
+ char tempStr[20];
+ sprintf(tempStr, "%ud", (unsigned long)getNodeType());
+ string result = string(tempStr);
+
+ if( elementNo == -1 )
+ result.append( elementName );
+ else
+ {
+ std::ostringstream bufferStream;
+ bufferStream << elementNo << ends;
+
+ result.append( bufferStream.str() );
+ }
+
+ result.append( "(" );
+ result.append( input->getSpelling() );
+ result.append( ")" );
+
+ return result;
+}
+
+
+QtData*
+QtDot::evaluate( QtDataList* inputList )
+{
+ RMDBCLASS( "QtDot", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if( getOperand( inputList, operand ) )
+ {
+ if( operand->getDataType() == QT_MDD )
+ {
+ QtMDD* mdd = (QtMDD*) operand;
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ // test, if operand has complex base type
+ if( mdd->getCellType()->getType() != STRUCT )
+ {
+ RMInit::logOut << "Internal error in QtDot::evaluate() - "
+ << "runtime type checking failed." << endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ StructType* operandType = (StructType*)mdd->getCellType();
+ unsigned int operandOffset;
+ const BaseType* resultCellType = NULL;
+
+ if( elementNo == -1 )
+ resultCellType = operandType->getElemType( (char*)(elementName.c_str()) );
+ else
+ resultCellType = operandType->getElemType( (unsigned int)elementNo );
+
+ if( !resultCellType )
+ {
+ RMInit::logOut << "Error: QtDot::evaluate() - struct selector is not valid." << endl;
+ parseInfo.setErrorNo(370);
+ throw parseInfo;
+ }
+
+ if( elementNo == -1 )
+ operandOffset = operandType->getOffset( (char*)(elementName.c_str()) );
+ else
+ operandOffset = operandType->getOffset( (unsigned int)elementNo );
+
+ RMDBGIF( 1, RMDebug::module_qlparser, "QtUnaryInduce", \
+ char* typeStructure = operandType->getTypeStructure(); \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtUnaryInduce", "Operand base type " << operandType->getTypeName() << ", structure " << typeStructure ) \
+ free( typeStructure ); typeStructure=NULL; \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtUnaryInduce", "Operand base offset " << operandOffset ) \
+ typeStructure = resultCellType->getTypeStructure(); \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtUnaryInduce", "Result base type " << resultCellType->getTypeName() << ", structure " << typeStructure ) \
+ free( typeStructure ); typeStructure=NULL; \
+ )
+
+ returnValue = computeUnaryMDDOp( mdd, resultCellType, Ops::OP_IDENTITY, operandOffset );
+ }
+ else if( operand->isScalarData() )
+ {
+ QtScalarData* scalar = (QtScalarData*) operand;
+
+#ifdef QT_RUNTIME_TYPE_CHECK
+ // test, if operand has complex base type
+ if( scalar->getValueType()->getType() != STRUCT )
+ {
+ RMInit::logOut << "Internal error in QtDot::evaluate() - "
+ << "runtime type checking failed." << endl;
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+
+ return 0;
+ }
+#endif
+
+ StructType* operandType = (StructType*)scalar->getValueType();
+ unsigned int operandOffset;
+ const BaseType* resultCellType=NULL;
+
+ if( elementNo == -1 )
+ resultCellType = operandType->getElemType( (char*)(elementName.c_str()) );
+ else
+ resultCellType = operandType->getElemType( (unsigned int)elementNo );
+
+ if( !resultCellType )
+ {
+ RMInit::logOut << "Error: QtDot::evaluate() - struct selector is not valid." << endl;
+ parseInfo.setErrorNo(370);
+ throw parseInfo;
+ }
+
+ if( elementNo == -1 )
+ operandOffset = operandType->getOffset( (char*)(elementName.c_str()) );
+ else
+ operandOffset = operandType->getOffset( (unsigned int)elementNo );
+
+ RMDBGIF( 1, RMDebug::module_qlparser, "QtUnaryInduce", \
+ char* typeStructure = operandType->getTypeStructure(); \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtUnaryInduce", "Operand scalar type " << operandType->getTypeName() << ", structure " << typeStructure ) \
+ free( typeStructure ); typeStructure=NULL; \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtUnaryInduce", "Operand scalar offset " << operandOffset ) \
+ typeStructure = resultCellType->getTypeStructure(); \
+ RMDBGMIDDLE( 4, RMDebug::module_qlparser, "QtUnaryInduce", "Result scalar type " << resultCellType->getTypeName() << ", structure " << typeStructure ) \
+ free( typeStructure ); typeStructure=NULL; \
+ )
+
+ returnValue = computeUnaryOp( scalar, resultCellType, Ops::OP_IDENTITY, operandOffset );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtDot::evaluate() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+
+ // delete old operand
+ if( operand ) operand->deleteRef();
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QtDot::printTree( int tab, ostream& s, QtChildType mode )
+{
+ if( elementNo == -1 )
+ s << SPACE_STR(tab).c_str() << "QtDot Object: access " << elementName.c_str() << endl;
+ else
+ s << SPACE_STR(tab).c_str() << "QtDot Object: access no " << elementNo << endl;
+
+ QtUnaryInduce::printTree( tab+2, s, mode );
+}
+
+void
+QtDot::printAlgebraicExpression( ostream& s )
+{
+ s << "(";
+
+ if( input )
+ input->printAlgebraicExpression( s );
+ else
+ s << "<nn>";
+
+ s << ").";
+
+ if( elementNo == -1 )
+ s << elementName.c_str();
+ else
+ s << elementNo;
+
+ s << " ";
+}
+
+const QtTypeElement&
+QtDot::checkType( QtTypeTuple* typeTuple )
+{
+ RMDBCLASS( "QtDot", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if( input )
+ {
+
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtDot", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+
+ if( inputType.getDataType() == QT_MDD )
+ {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+
+ // test, if operand has complex base type
+ if( baseType->getType() != STRUCT )
+ {
+ RMInit::logOut << "Error: QtDot::evaluate() - operand of induce dot operation must be complex." << endl;
+ parseInfo.setErrorNo(368);
+ throw parseInfo;
+ }
+
+ StructType* structType = (StructType*)baseType;
+ const BaseType* resultBaseType = NULL;
+
+ if( elementNo == -1 )
+ resultBaseType = structType->getElemType( (char*)(elementName.c_str()) );
+ else
+ resultBaseType = structType->getElemType( (unsigned int)elementNo );
+
+ if( !resultBaseType )
+ {
+ RMInit::logOut << "Error: QtDot::evaluate() - struct selector is not valid." << endl;
+ parseInfo.setErrorNo(370);
+ throw parseInfo;
+ }
+
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+
+ dataStreamType.setType( resultMDDType );
+ }
+ else if( inputType.isBaseType() )
+ {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+
+ // test, if operand has complex base type
+ if( baseType->getType() != STRUCT )
+ {
+ RMInit::logOut << "Error: QtDot::evaluate() - operand of dot operation must be complex." << endl;
+ parseInfo.setErrorNo(369);
+ throw parseInfo;
+ }
+
+ StructType* structType = (StructType*)baseType;
+ const BaseType* resultBaseType = NULL;
+
+ if( elementNo == -1 )
+ resultBaseType = structType->getElemType( (char*)(elementName.c_str()) );
+ else
+ resultBaseType = structType->getElemType( (unsigned int)elementNo );
+
+ if( !resultBaseType )
+ {
+ RMInit::logOut << "Error: QtDot::evaluate() - struct selector is not valid." << endl;
+ parseInfo.setErrorNo(370);
+ throw parseInfo;
+ }
+
+ dataStreamType.setType( resultBaseType );
+ }
+ else
+ {
+ RMInit::logOut << "Error: QtDot::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ } else
+ RMInit::logOut << "Error: QtDot::checkType() - operand branch invalid." << endl;
+ return dataStreamType;
+}
+
+//--------------------------------------------
+// QtCast
+//--------------------------------------------
+
+const QtNode::QtNodeType QtCast::nodeType = QtNode::QT_CAST;
+
+QtCast::QtCast(QtOperation* initInput, cast_types t):
+ QtUnaryInduce(initInput), castType(t) {}
+
+QtData* QtCast::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand))
+ returnValue = computeOp( operand, getOp(castType));
+
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtCast::printTree(int tab, ostream& s, QtChildType mode) {
+ const char *type_name[] = {
+ "bool", "octet", "char", "short", "ushort",
+ "long", "ulong", "float", "double"
+ };
+ s << SPACE_STR(tab).c_str() << "QtCastObject "
+ << getNodeType()
+ << "<" << type_name[castType] << ">"
+ << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+
+void QtCast::printAlgebraicExpression(ostream& s) {
+ const char *type_name[] = {
+ "bool", "octet", "char", "short", "ushort",
+ "long", "ulong", "float", "double"
+ };
+ s << "cast<" << type_name[castType] << ">(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtCast::checkType(QtTypeTuple* typeTuple) {
+
+ RMDBCLASS( "QtCast", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if(input) {
+
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtCast", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( getOp(castType), baseType ));
+
+
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtCast::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( getOp(castType), baseType ));
+
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtCast::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtCast::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtCast::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+
+//--------------------------------------------
+// QtRealPartOp
+//--------------------------------------------
+
+const QtNode::QtNodeType QtRealPartOp::nodeType = QtNode::QT_REALPART;
+
+QtRealPartOp::QtRealPartOp(QtOperation* initInput): QtUnaryInduce(initInput) {}
+
+QtData* QtRealPartOp::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand))
+ returnValue = computeOp( operand, Ops::OP_REALPART );
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtRealPartOp::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtRealPartOpObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+
+void QtRealPartOp::printAlgebraicExpression(ostream& s) {
+ s << "Re(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtRealPartOp::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtRealPartOp", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if(input) {
+
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+ RMDBGIF( 1, RMDebug::module_qlparser, "QtRealPartOp", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl;
+ )
+
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_REALPART, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtRealPartOp::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_REALPART, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtRealPartOp::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtRealPartOp::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ } else
+ RMInit::logOut << "Error: QtRealPartOp::checkType() - operand branch invalid." << endl;
+
+ return dataStreamType;
+}
+
+//--------------------------------------------
+// QtImaginarPartOp
+//--------------------------------------------
+
+const QtNode::QtNodeType QtImaginarPartOp::nodeType = QtNode::QT_IMAGINARPART;
+
+QtImaginarPartOp::QtImaginarPartOp(QtOperation* initInput): QtUnaryInduce(initInput) {}
+
+QtData* QtImaginarPartOp::evaluate(QtDataList* inputList) {
+ QtData* returnValue = NULL;
+ QtData* operand = NULL;
+
+ if(getOperand(inputList, operand))
+ returnValue = computeOp( operand, Ops::OP_IMAGINARPART );
+ // delete old operand
+ if(operand) operand->deleteRef();
+ return returnValue;
+}
+
+void QtImaginarPartOp::printTree(int tab, ostream& s, QtChildType mode) {
+ s << SPACE_STR(tab).c_str() << "QtImaginarPartObject " << getNodeType() << endl;
+ QtUnaryInduce::printTree( tab + 2, s, mode );
+}
+
+void QtImaginarPartOp::printAlgebraicExpression(ostream& s) {
+ s << "Im(";
+ if(input)
+ input->printAlgebraicExpression(s);
+ else
+ s << "<nn>";
+ s << ")";
+}
+
+const QtTypeElement& QtImaginarPartOp::checkType(QtTypeTuple* typeTuple) {
+ RMDBCLASS( "QtImaginarPart", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ // check operand branches
+ if(input)
+ {
+
+ // get input types
+ const QtTypeElement& inputType = input->checkType( typeTuple );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtImaginarPartOp", \
+ RMInit::dbgOut << "Operand: " << flush; \
+ inputType.printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+
+ if(inputType.getDataType() == QT_MDD) {
+ const BaseType* baseType = ((MDDBaseType*)(inputType.getType()))->getBaseType();
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType( Ops::OP_IMAGINARPART, baseType ));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtImaginarPart::checkType() - induce operand type is not support" << endl;
+ parseInfo.setErrorNo(366);
+ throw parseInfo;
+ }
+ MDDBaseType* resultMDDType = new MDDBaseType( "tmp", resultBaseType );
+ TypeFactory::addTempType( resultMDDType );
+ dataStreamType.setType( resultMDDType );
+ }
+ else if(inputType.isBaseType()) {
+ BaseType* baseType = (BaseType*)(inputType.getType());
+ BaseType* resultBaseType = (BaseType*)(Ops::getResultType(Ops::OP_IMAGINARPART, baseType));
+ if(!resultBaseType) {
+ RMInit::logOut << "Error: QtImaginarPart::checkType() - operand type is not supported." << endl;
+ parseInfo.setErrorNo(367);
+ throw parseInfo;
+ }
+ dataStreamType.setType( resultBaseType );
+ }
+ else {
+ RMInit::logOut << "Error: QtImaginarPart::checkType() - operation is not supported for strings." << endl;
+ parseInfo.setErrorNo(385);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtImaginarPart::checkType() - operand branch invalid." << endl;
+ return dataStreamType;
+}
+
+#include "autogen_qtui.cc"
diff --git a/qlparser/qtunaryinduce.hh b/qlparser/qtunaryinduce.hh
new file mode 100644
index 0000000..ebd69d4
--- /dev/null
+++ b/qlparser/qtunaryinduce.hh
@@ -0,0 +1,267 @@
+#ifndef _QTUNARYINDUCE_HH_
+#define _QTUNARYINDUCE_HH_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include "qlparser/qtunaryoperation.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtatomicdata.hh"
+
+#include "catalogmgr/ops.hh"
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+This class has just QtNot as subclass which represents the not operations
+{\tt MDD<Bool> -> MDD<Bool>} and {\tt MDD<Int> -> MDD<Int>}.
+
+*/
+
+class QtUnaryInduce : public QtUnaryOperation
+{
+ public:
+ /// constructor getting the operand
+ QtUnaryInduce( QtOperation* input );
+
+ protected:
+ /// computes the unary operation
+ QtData* computeOp( QtData* operand, Ops::OpType operation );
+
+ /// method for testing and evaluating the input branch
+ bool getOperand( QtDataList* inputList, QtData* &operand );
+ /**
+ The method checks if the input branch is valid. Then it passes the evaluate message to its
+ operand with the {\tt inputList} as argument. The returned result is provided through the argument
+ {\tt operand} called by reference. The method returns {\tt true} it the operand is
+ valid, otherwise {\tt false}.
+ */
+
+ /// computes an unary induce operation with one MDD object
+ QtData* computeUnaryMDDOp( QtMDD* operand, const BaseType* resultBaseType, Ops::OpType operation, unsigned int operandOffset = 0 );
+ /**
+ The method carries out the unary induce operation specified by {\tt operation} on the operand. For
+ the result, a new transient MDD object is created and returned. In the end, the MDD object of the operand
+ is freed.
+ */
+
+ /// computes an unary induce operation with one MDD object
+ QtData* computeUnaryOp( QtScalarData* operand, const BaseType* resultBaseType, Ops::OpType operation, unsigned int operandOffset = 0 );
+ /**
+ The method carries out the unary operation specified by {\tt operation} on the operand.
+ */
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtNot : public QtUnaryInduce
+{
+ public:
+ /// constructor getting the operand
+ QtNot( QtOperation* input );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+
+ /**
+ The method invokes the evaluate method of its superclass {\tt QtUnaryInduce} with the not
+ operation as an additional argument to compute the result of the node.
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtDot : public QtUnaryInduce
+{
+ public:
+ /// constructor getting operand and element name
+ QtDot( const std::string& elementName );
+
+ /// constructor getting operand and element number
+ QtDot( unsigned int elementNo );
+
+ /// creates a unique name for a common subexpression
+ virtual std::string getSpelling();
+
+ /// tests if the two nodes have an equal meaning in the query tree
+ virtual bool equalMeaning( QtNode* node );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList );
+ /**
+ The method invokes the evaluate method of its superclass {\tt QtUnaryInduce} with the not
+ operation as an additional argument to compute the result of the node.
+ */
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL );
+
+ private:
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+
+ /// attribute storing selection element name
+ std::string elementName;
+
+ /// attribute storing selection element number
+ int elementNo;
+ /**
+ The number is either positive, which means that the number
+ is valid, or -1 saying that the element name is valid for
+ selection.
+ */
+};
+
+
+//--------------------------------------------
+// QtCast
+//--------------------------------------------
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+QtCast provides type conversions
+*/
+
+class QtCast : public QtUnaryInduce {
+public:
+ enum cast_types {
+ t_bool, t_octet, t_char, t_short, t_ushort,
+ t_long, t_ulong, t_float, t_double
+ };
+
+ QtCast(QtOperation*, cast_types);
+ /// method for evaluating the node
+ QtData* evaluate(QtDataList*);
+ /// prints the tree
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES);
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ /// retrives node type
+ inline virtual const QtNodeType getNodeType() const;
+ /// semantics check
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL );
+
+private:
+ Ops::OpType getOp(cast_types);
+
+ static const QtNodeType nodeType;
+ cast_types castType;
+};
+
+
+//--------------------------------------------
+// QtRealPartOp
+//--------------------------------------------
+
+class QtRealPartOp : public QtUnaryInduce {
+public:
+ QtRealPartOp(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES);
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL);
+
+private:
+ static const QtNodeType nodeType;
+};
+
+//--------------------------------------------
+// QtImaginarPartOp
+//--------------------------------------------
+
+class QtImaginarPartOp : public QtUnaryInduce {
+public:
+ QtImaginarPartOp(QtOperation*);
+ QtData* evaluate(QtDataList*);
+ virtual void printTree(int, std::ostream& = std::cout, QtChildType = QT_ALL_NODES);
+ virtual void printAlgebraicExpression(std::ostream& = std::cout);
+ inline virtual const QtNodeType getNodeType() const;
+ virtual const QtTypeElement& checkType(QtTypeTuple* = NULL);
+
+private:
+ static const QtNodeType nodeType;
+};
+
+#include "autogen_qtui.hh"
+#include "qlparser/qtunaryinduce.icc"
+#include "autogen_qtui.icc"
+
+
+#endif
+
diff --git a/qlparser/qtunaryinduce.icc b/qlparser/qtunaryinduce.icc
new file mode 100644
index 0000000..80691a4
--- /dev/null
+++ b/qlparser/qtunaryinduce.icc
@@ -0,0 +1,84 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+inline const QtNode::QtNodeType
+QtNot::getNodeType() const
+{
+ return nodeType;
+}
+
+
+
+inline const QtNode::QtNodeType
+QtDot::getNodeType() const
+{
+ return nodeType;
+}
+
+
+//---- QtCast ----
+
+inline const QtNode::QtNodeType QtCast::getNodeType() const {
+ return nodeType;
+}
+
+inline Ops::OpType QtCast::getOp(QtCast::cast_types t) {
+ Ops::OpType c=Ops::OP_CAST_BOOL;
+ switch(t) {
+ case QtCast::t_bool: c=Ops::OP_CAST_BOOL; break;
+ case QtCast::t_octet: c=Ops::OP_CAST_OCTET; break;
+ case QtCast::t_char: c=Ops::OP_CAST_CHAR; break;
+ case QtCast::t_short: c=Ops::OP_CAST_SHORT; break;
+ case QtCast::t_ushort: c=Ops::OP_CAST_USHORT; break;
+ case QtCast::t_long: c=Ops::OP_CAST_LONG; break;
+ case QtCast::t_ulong: c=Ops::OP_CAST_ULONG; break;
+ case QtCast::t_float: c=Ops::OP_CAST_FLOAT; break;
+ case QtCast::t_double: c=Ops::OP_CAST_DOUBLE; break;
+ default: RMInit::logOut << "Error: QtCast::getOp - undefined cast type." << endl; break;
+ }
+ return c;
+}
+
+
+//---- QtRealPartOp ----
+
+inline const QtNode::QtNodeType QtRealPartOp::getNodeType() const {
+ return nodeType;
+}
+
+//---- QtImaginarPartOp ----
+
+inline const QtNode::QtNodeType QtImaginarPartOp::getNodeType() const {
+ return nodeType;
+}
+
+
+//----------------
+
diff --git a/qlparser/qtunaryoperation.cc b/qlparser/qtunaryoperation.cc
new file mode 100644
index 0000000..e05bb23
--- /dev/null
+++ b/qlparser/qtunaryoperation.cc
@@ -0,0 +1,204 @@
+/*
+* 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, QtUnaryOperation: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtunaryoperation.cc,v 1.23 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "qlparser/qtunaryoperation.hh"
+#include "qlparser/qtconst.hh"
+
+#include <iostream>
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+
+QtUnaryOperation::QtUnaryOperation()
+ : QtOperation(),
+ input(NULL)
+{
+}
+
+
+QtUnaryOperation::QtUnaryOperation( QtOperation* inputInit )
+ : QtOperation(),
+ input( inputInit )
+{
+ if( input )
+ input->setParent( this );
+}
+
+
+QtUnaryOperation::~QtUnaryOperation()
+{
+ if( input )
+ {
+ delete input;
+ input=NULL;
+ }
+}
+
+
+
+string
+QtUnaryOperation::getSpelling()
+{
+ char tempStr[20];
+ sprintf(tempStr, "%ud", (unsigned long)getNodeType());
+ string result = string(tempStr);
+ result.append( "(" );
+ result.append( input->getSpelling() );
+ result.append( ")" );
+
+ return result;
+}
+
+
+
+void
+QtUnaryOperation::simplify()
+{
+ RMDBCLASS( "QtUnaryOperation", "simplify()", "qlparser", __FILE__, __LINE__ )
+
+ // In order to work bottom up, first inspect the descendants
+ QtNode::simplify();
+
+ // Test, if operand is available.
+ if( input )
+ {
+ // Test, if operand is of const type.
+ if( input->getNodeType() == QT_CONST )
+ {
+ // evaluate the self node with no input list
+ QtData* newConst = this->evaluate( NULL );
+
+ if( newConst )
+ {
+ // create a new constant node and fill it with newConst
+ QtConst* newNode = new QtConst( newConst );
+
+ // set its data stream type
+ newNode->checkType( NULL );
+
+ // link it to the parent
+ getParent()->setInput( this, newNode );
+
+ // delete the self node and its descendants
+ delete this;
+ }
+ }
+ }
+}
+
+
+
+bool
+QtUnaryOperation::equalMeaning( QtNode* node )
+{
+ RMDBCLASS( "QtUnaryOperation", "equalMeaning( QtNode* )", "qlparser", __FILE__, __LINE__ )
+
+ bool result = false;
+
+ if( getNodeType() == node->getNodeType() )
+ {
+ QtUnaryOperation* unaryNode = (QtUnaryOperation*) node; // by force
+
+ result = input->equalMeaning( unaryNode->getInput() );
+ };
+
+ return ( result );
+}
+
+
+
+QtNode::QtNodeList*
+QtUnaryOperation::getChilds( QtChildType flag )
+{
+ RMDBCLASS( "QtUnaryOperation", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
+
+ QtNodeList* resultList=NULL;
+
+ if( flag == QT_DIRECT_CHILDS )
+ resultList = new QtNodeList();
+
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ resultList = input->getChilds( flag );
+
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( input );
+
+ return resultList;
+}
+
+
+QtNode::QtAreaType
+QtUnaryOperation::getAreaType()
+{
+ return( input->getAreaType() );
+}
+
+
+void
+QtUnaryOperation::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtUnaryOperation", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ // by default, pass load domain to the input
+ if( input )
+ input->optimizeLoad( trimList );
+ else
+ {
+ delete trimList;
+ trimList=NULL;
+ }
+}
+
+
+void
+QtUnaryOperation::printTree( int tab, ostream& s, QtChildType mode )
+{
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ if( input )
+ {
+ s << SPACE_STR(tab).c_str() << "input: " << endl;
+ input->printTree( tab+2, s, mode );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no input" << endl;
+}
+
+
+
+
+
+
diff --git a/qlparser/qtunaryoperation.hh b/qlparser/qtunaryoperation.hh
new file mode 100644
index 0000000..e7602b8
--- /dev/null
+++ b/qlparser/qtunaryoperation.hh
@@ -0,0 +1,111 @@
+#ifndef _QTUNARYOPERATION_
+#define _QTUNARYOPERATION_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include <stdio.h>
+
+#include "qlparser/qtoperation.hh"
+
+/*
+* 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>.
+*/
+/**************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+The class serves as superclass for all operation classes taking one
+argument.
+
+*/
+
+class QtUnaryOperation : public QtOperation
+{
+ public:
+ /// default constructor
+ QtUnaryOperation();
+
+ /// constructor getting the node to its operand
+ QtUnaryOperation( QtOperation* input );
+
+ /// virtual destructor
+ virtual ~QtUnaryOperation();
+
+ /// creates a unique name for a common subexpression
+ virtual std::string getSpelling();
+
+ /// simplifies the tree
+ virtual void simplify();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// test if the edge to the parent node is of type mdd or atomic
+ virtual QtAreaType getAreaType();
+
+ /// tests if the two nodes have an equal meaning in the query tree
+ virtual bool equalMeaning( QtNode* node );
+
+ /// method for query rewrite
+ inline virtual void setInput( QtOperation* inputOld, QtOperation* inputNew );
+
+ /// optimizing load access
+ virtual void optimizeLoad( QtTrimList* trimList );
+
+ /**
+ The method passes the given {\tt trimList} list to its input tree.
+ */
+
+ /// debugging method
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ //@Man: Read/Write methods for the operand
+ //@{
+ ///
+
+ ///
+ inline virtual void setInput( QtOperation* input );
+ ///
+ inline QtOperation* getInput();
+
+ //@}
+
+ protected:
+ /// operation operand
+ QtOperation* input;
+};
+
+#include "qlparser/qtunaryoperation.icc"
+
+#endif
+
diff --git a/qlparser/qtunaryoperation.icc b/qlparser/qtunaryoperation.icc
new file mode 100644
index 0000000..a208cdc
--- /dev/null
+++ b/qlparser/qtunaryoperation.icc
@@ -0,0 +1,59 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline void
+QtUnaryOperation::setInput( QtOperation* inputNew )
+{
+ input = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+};
+
+
+inline void
+QtUnaryOperation::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ if( input == inputOld )
+ {
+ input = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+};
+
+
+inline QtOperation*
+QtUnaryOperation::getInput()
+{
+ return input;
+};
+
+
diff --git a/qlparser/qtupdate.cc b/qlparser/qtupdate.cc
new file mode 100644
index 0000000..a5ca731
--- /dev/null
+++ b/qlparser/qtupdate.cc
@@ -0,0 +1,812 @@
+/*
+* 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, QtUpdate: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtupdate.cc,v 1.28 2003/12/27 20:51:28 rasdev Exp $";
+
+#include "raslib/dlist.hh"
+
+#include "qlparser/qtupdate.hh"
+#include "qlparser/qtdata.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtmintervaldata.hh"
+
+#include "tilemgr/tile.hh"
+#include "tilemgr/tiler.hh"
+
+#include "mddmgr/mddobj.hh"
+
+#include <iostream>
+#include <memory>
+
+
+const QtNode::QtNodeType QtUpdate::nodeType = QtNode::QT_UPDATE;
+
+
+
+QtUpdate::QtUpdate( QtOperation* initUpdateTarget, QtOperation* initUpdateDomain, QtOperation* initUpdateSource )
+ : QtExecute(), input(NULL),
+ updateTarget( initUpdateTarget ),
+ updateDomain( initUpdateDomain ),
+ updateSource( initUpdateSource )
+{
+ if( updateTarget ) updateTarget->setParent( this );
+ if( updateDomain ) updateDomain->setParent( this );
+ if( updateSource ) updateSource->setParent( this );
+}
+
+
+
+QtUpdate::~QtUpdate()
+{
+ if( updateTarget )
+ {
+ delete updateTarget;
+ updateTarget=NULL;
+ }
+
+ if( updateDomain )
+ {
+ delete updateDomain;
+ updateDomain=NULL;
+ }
+
+ if( updateSource )
+ {
+ delete updateSource;
+ updateSource=NULL;
+ }
+
+ if( input )
+ {
+ delete input;
+ input=NULL;
+ }
+}
+
+
+
+int
+QtUpdate::evaluate()
+{
+ RMDBCLASS( "QtUpdate", "evaluate()", "qlparser", __FILE__, __LINE__ )
+
+ // Test, if all necessary operands are available.
+ if( updateTarget && updateSource && input )
+ {
+ QtNode::QtDataList* nextTupel;
+
+ // open input stream
+ try
+ {
+ input->open();
+ }
+ catch( ... )
+ {
+ input->close();
+ throw;
+ }
+
+ try
+ {
+ while( (nextTupel = input->next()) )
+ {
+ // get obligatory operands
+ QtData* target = updateTarget->evaluate( nextTupel );
+ QtData* source = updateSource->evaluate( nextTupel );
+
+ // Test, if the operands are valid.
+ if( target && source )
+ {
+ // check update target
+ if( target->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtUpdate::evaluate() - update target must be an iterator variable." << endl;
+
+ // delete tupel vector received by next()
+ for( vector<QtData*>::iterator dataIter=nextTupel->begin();
+ dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+
+ // delete the operands
+ if( target ) target->deleteRef();
+ if( source ) source->deleteRef();
+
+ parseInfo.setErrorNo(950);
+ throw parseInfo;
+ }
+
+ // check update source
+ if( source->getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtUpdate::evaluate() - update source must be an expression resulting in an MDD" << endl;
+
+ // delete tupel vector received by next()
+ for( vector<QtData*>::iterator dataIter=nextTupel->begin();
+ dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+
+ // delete the operands
+ if( target ) target->deleteRef();
+ if( source ) source->deleteRef();
+
+ parseInfo.setErrorNo(951);
+ throw parseInfo;
+ }
+
+ QtMDD* targetMDD = (QtMDD*) target;
+ QtMDD* sourceMDD = (QtMDD*) source;
+
+ MDDObj* targetObj = targetMDD->getMDDObject();
+ MDDObj* sourceObj = sourceMDD->getMDDObject();
+
+ // test, if target is a persistent object
+ if( !targetObj->isPersistent() )
+ {
+ RMInit::logOut << "Error: QtUpdate::evaluate() - result of target expression must be an assignable value (l-value)." << endl;
+
+ // delete tupel vector received by next()
+ for( vector<QtData*>::iterator dataIter=nextTupel->begin();
+ dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+
+ // delete the operands
+ if( target ) target->deleteRef();
+ if( source ) source->deleteRef();
+
+ parseInfo.setErrorNo(954);
+ throw parseInfo;
+ }
+
+ // get optional domain
+ QtData* domainData = NULL;
+ r_Minterval domain;
+
+ if( updateDomain )
+ {
+ domainData = updateDomain->evaluate( nextTupel );
+
+ if( domainData )
+ domain = ((QtMintervalData*)domainData)->getMintervalData();
+ }
+
+ RMDBGIF( 1, RMDebug::module_qlparser, "QtUpdate", \
+ if( domainData ) \
+ RMInit::dbgOut << endl << " target MDD, domain " << domain << endl; \
+ else \
+ RMInit::dbgOut << endl << " target MDD" << endl; \
+
+ targetMDD->printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl << " source MDD" << endl; \
+ sourceMDD->printStatus( RMInit::dbgOut ); \
+ RMInit::dbgOut << endl; \
+ )
+
+ // 1st update strategy:
+ //
+ // 1. All cell values of the source domain which are already defined are
+ // updated with the corresponding new values.
+ // 2. If a source tile does not intersect with any tile of the target
+ // object, it is inserted.
+
+ // In case of update domain existence, test for compatibility.
+ if( domainData )
+ {
+ // Dimensionality of the udate domain specification has to be equal to
+ // the target MDD dimensionality.
+ if( domain.dimension() != targetMDD->getLoadDomain().dimension() )
+ {
+ RMInit::logOut << "Error: QtUpdate::evaluate() - Update domain dimensionality must match target MDD dimensionaltiy." << endl;
+
+ // delete tupel vector received by next()
+ for( vector<QtData*>::iterator dataIter=nextTupel->begin();
+ dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+
+ // delete the operands
+ if( target ) target->deleteRef();
+ if( domainData ) domainData->deleteRef();
+ if( source ) source->deleteRef();
+
+ parseInfo.setErrorNo(963);
+ throw parseInfo;
+ }
+
+ // The number of interval dimension of the update domain has to be
+ // equal to the number of dimensions of the source domain.
+ int updateIntervals = 0;
+
+ const vector<bool>* trimFlags = ((QtMintervalData*)domainData)->getTrimFlags();
+ for( int i=0; i<trimFlags->size(); i++ )
+ if( (*trimFlags)[i] )
+ updateIntervals++;
+
+ if( updateIntervals != sourceMDD->getLoadDomain().dimension() )
+ {
+ RMInit::logOut << "Error: QtUpdate::evaluate() - Number of update intervals must match source dimensionality." << endl;
+
+ // delete tupel vector received by next()
+ for( vector<QtData*>::iterator dataIter=nextTupel->begin();
+ dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+
+ // delete the operands
+ if( target ) target->deleteRef();
+ if( domainData ) domainData->deleteRef();
+ if( source ) source->deleteRef();
+
+ parseInfo.setErrorNo(962);
+ throw parseInfo;
+ }
+
+ // Warning: Fixed bounds in update domain specifications are ignored.
+ }
+
+ r_Minterval sourceMDDDomain( sourceMDD->getLoadDomain() );
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "source mdd domain " << sourceMDDDomain )
+
+ // compute source MDD domain taking into account update domain
+ if( domainData )
+ {
+ const vector<bool>* trimFlags = ((QtMintervalData*)domainData)->getTrimFlags();
+ r_Minterval newSourceMDDDomain( targetMDD->getLoadDomain().dimension() );
+
+ for( int i=0, j=0; i<trimFlags->size(); i++ )
+ if( (*trimFlags)[i] )
+ newSourceMDDDomain << sourceMDDDomain[j++];
+ else
+ newSourceMDDDomain << domain[i];
+
+ sourceMDDDomain = newSourceMDDDomain;
+
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "source update domain " << sourceMDDDomain )
+ }
+ // check if you may update that are ( you should not go out of bounds for mdddomaintype )
+ if (!targetObj->getMDDBaseType()->compatibleWithDomain(&sourceMDDDomain))
+ {
+ RMInit::logOut << "Error: QtUpdate::evaluate() - The update domain is outside the allowed domain of the target mdd." << endl;
+
+ // delete tupel vector received by next()
+ for( vector<QtData*>::iterator dataIter=nextTupel->begin();
+ dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+
+ // delete the operands
+ if( target ) target->deleteRef();
+ if( domainData ) domainData->deleteRef();
+ if( source ) source->deleteRef();
+
+ parseInfo.setErrorNo(953);
+ throw parseInfo;
+
+ }
+ //
+ // get all source tiles
+ //
+ vector<Tile*>* sourceTiles = sourceObj->getTiles();
+RMDBGIF(1, RMDebug::module_qlparser, "QtUpdate", \
+ if (sourceTiles) \
+ RMDBGMIDDLE(1, RMDebug::module_qlparser, "QtUpdate", "there are " << sourceTiles->size() << " source tiles") \
+ else \
+ RMDBGMIDDLE(1, RMDebug::module_qlparser, "QtUpdate", "there are no source tiles") )
+
+ //
+ // get all target tiles in the relevant area
+ //
+
+ vector<Tile*>* targetTiles = NULL;
+//this is not a very good idea
+// try{
+ targetTiles = targetObj->intersect( sourceMDDDomain );
+/* }
+ catch(...)
+ {
+ RMInit::logOut << "BUG of MDDObj::intersect" << endl;
+ targetTiles = new vector<Tile*>;
+ }
+*/
+ if( !targetTiles )
+ {
+ targetTiles = new vector<Tile*>;
+ RMDBGMIDDLE(1, RMDebug::module_qlparser, "QtUpdate", "found no target tiles")
+ }
+ else {
+ RMDBGMIDDLE(1, RMDebug::module_qlparser, "QtUpdate", "found " << targetTiles->size() << " target tiles in mdd")
+ }
+
+ //
+ // iterate over source tiles
+ //
+ unsigned long targetTileArea = 0;
+ unsigned long sourceTileArea = 0;
+ unsigned long targetTileDomain = 0;
+ unsigned long updatedArea = 0;
+ bool computed = false;
+ vector<r_Minterval> insertedDomains;
+ vector<r_Minterval> sourceDomains;
+ vector<r_Minterval> targetDomains;
+ vector<r_Minterval>::iterator domIt;
+ vector<r_Minterval>::iterator intervalIt;
+ vector<Tile*> retval;
+ vector<Tile*>::iterator retvalIt;
+ vector<Tile*>::iterator sourceIt;
+ vector<Tile*>::iterator targetIt;
+ sourceIt = sourceTiles->begin();
+ //this lives here because we don't want memory leaks because of exceptions
+ //of course we seldom use this operation ( as we use copy tile most of the time )
+
+ UnaryOp* tempOp = NULL;
+ if (sourceIt != sourceTiles->end())
+ tempOp = Ops::getUnaryOp(Ops::OP_IDENTITY, targetObj->getCellType(), (*sourceIt)->getType(), 0, 0);
+ std::auto_ptr<UnaryOp> myOp(tempOp);
+ for( ; sourceIt != sourceTiles->end(); sourceIt++ )
+ {
+ // calculate relevant area of source tile
+ r_Minterval sourceTileDomain = (*sourceIt)->getDomain().create_intersection( sourceMDD->getLoadDomain() );
+
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "original source tile domain " << sourceTileDomain )
+
+ // compute update source tile domain taking into account update domain
+ r_Minterval updateSourceTileDomain;
+
+ if( domainData )
+ {
+ updateSourceTileDomain = r_Minterval( targetMDD->getLoadDomain().dimension() );
+ const vector<bool>* trimFlags = ((QtMintervalData*)domainData)->getTrimFlags();
+
+ for( int i=0, j=0; i<trimFlags->size(); i++ )
+ if( (*trimFlags)[i] )
+ updateSourceTileDomain << sourceTileDomain[j++];
+ else
+ updateSourceTileDomain << domain[i];
+ }
+ else
+ updateSourceTileDomain = sourceTileDomain;
+
+ //calculate number of cells in this area
+ sourceTileArea = sourceTileArea + sourceTileDomain.cell_count();
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "update source tile domain " << updateSourceTileDomain )
+
+ bool intersection = false;
+
+ for( targetIt = targetTiles->begin(); targetIt != targetTiles->end(); targetIt++ )
+ {
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "target tile domain " << (*targetIt)->getDomain())
+ if (!computed)
+ {
+ targetTileArea = targetTileArea + sourceMDDDomain.create_intersection((*targetIt)->getDomain()).cell_count();
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "target area sum " << targetTileArea)
+ }
+ // if tiles are intersecting
+ if( updateSourceTileDomain.intersects_with( (*targetIt)->getDomain() ) )
+ {
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "source tile domain " << updateSourceTileDomain << " intersects with target domain " << (*targetIt)->getDomain())
+ intersection = true;
+
+ // get intersecting updateSourceTileDomain
+ r_Minterval intersectUpdateSourceTileDomain = updateSourceTileDomain.create_intersection( (*targetIt)->getDomain() );
+
+ // compute corresponding sourceTileDomain
+ r_Minterval intersectSourceTileDomain = intersectUpdateSourceTileDomain;
+ if( domainData )
+ {
+ const vector<bool>* trimFlags = ((QtMintervalData*)domainData)->getTrimFlags();
+
+ for( int i=0, j=0; i<trimFlags->size(); i++ )
+ if( !((*trimFlags)[i]) )
+ intersectSourceTileDomain.delete_dimension( j );
+ else
+ j++;
+ }
+
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "update domains: target tile " << (*targetIt)->getDomain() << " update target at " << intersectUpdateSourceTileDomain << ", source tile " << (*sourceIt)->getDomain() << " update with data at " << intersectSourceTileDomain )
+ //(*targetIt)->execUnaryOp( Ops::OP_IDENTITY, intersectUpdateSourceTileDomain, *sourceIt, intersectSourceTileDomain );
+ (*targetIt)->copyTile(intersectUpdateSourceTileDomain, *sourceIt, intersectSourceTileDomain);
+ updatedArea = updatedArea + intersectUpdateSourceTileDomain.cell_count();
+ }
+ }
+ computed = true;
+ // insert the tile
+ if (!intersection)
+ {
+ // Create a new persistent tile, copy the transient data,
+ // and insert it into the target mdd object.
+ Tile* newPersTile = new Tile(updateSourceTileDomain, targetObj->getCellType(), (*sourceIt)->getDataFormat());
+ if (updateSourceTileDomain.dimension() == sourceTileDomain.dimension())
+ newPersTile->copyTile( updateSourceTileDomain, *sourceIt, sourceTileDomain );
+ else
+ newPersTile->execUnaryOp( &(*myOp), updateSourceTileDomain, *sourceIt, sourceTileDomain );
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "update domains: target tile " << newPersTile->getDomain() << " update target at " << updateSourceTileDomain << ", source tile " << (*sourceIt)->getDomain() << " update with data at " << sourceTileDomain )
+ // this will make a crash in updateset3 because of a strange triming doman
+ //newPersTile->copyTile(updateSourceTileDomain, *sourceIt, sourceTileDomain);
+
+ targetObj->insertTile( newPersTile );
+ updatedArea = updatedArea + updateSourceTileDomain.cell_count();
+ insertedDomains.push_back((*sourceIt)->getDomain());
+ }
+ }//for is done
+
+ if (sourceTileArea > updatedArea)
+ {
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "the source area was not updated completely, tiling the rest")
+ while (!insertedDomains.empty())
+ {
+ intervalIt = insertedDomains.begin();
+ for (sourceIt = sourceTiles->begin(); sourceIt != sourceTiles->end(); sourceIt++)
+ if ((*sourceIt)->getDomain() == *intervalIt)
+ {
+ sourceTiles->erase(sourceIt);
+ break;
+ }
+ insertedDomains.erase(intervalIt);
+ }
+ for (sourceIt = sourceTiles->begin(); sourceIt != sourceTiles->end(); sourceIt++)
+ sourceDomains.push_back((*sourceIt)->getDomain());
+ for (targetIt = targetTiles->begin(); targetIt != targetTiles->end(); targetIt++)
+ targetDomains.push_back((*targetIt)->getDomain());
+ r_Tiler t(sourceDomains, targetDomains);
+ t.split();
+ t.removeDoubleDomains();
+ t.removeCoveredDomains();
+ t.mergeDomains();
+ retval = t.generateTiles(*sourceTiles);
+ for (retvalIt = retval.begin(); retvalIt != retval.end(); retvalIt++)
+ {
+ targetObj->insertTile((Tile*)(*retvalIt));
+ }
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtUpdate", "insertion of the rest is done")
+ }
+
+ // delete tile vectors
+ delete sourceTiles;
+ sourceTiles=NULL;
+ delete targetTiles;
+ targetTiles=NULL;
+
+ // delete optional operand
+ if( domainData ) domainData->deleteRef();
+ }
+ else
+ RMInit::logOut << "Error: QtUpdate::evaluate() - target or source is not provided." << endl;
+
+ // delete the operands
+ if( target ) target->deleteRef();
+ if( source ) source->deleteRef();
+
+ // delete tupel vector received by next()
+ for( vector<QtData*>::iterator dataIter=nextTupel->begin();
+ dataIter!=nextTupel->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete nextTupel;
+ nextTupel=NULL;
+
+ } // while
+
+ }
+ catch( ... )
+ {
+ input->close();
+ throw;
+ }
+
+ input->close();
+ }
+ else
+ RMInit::logOut << "Error: QtUpdate::evaluate() - at least one operand branch is invalid." << endl;
+
+ return 0;
+}
+
+
+
+QtNode::QtNodeList*
+QtUpdate::getChilds( QtChildType flag )
+{
+ RMDBCLASS( "QtUpdate", "getChilds( QtChildType flag )", "qlparser", __FILE__, __LINE__ )
+
+ QtNodeList* resultList=NULL;
+
+ // allocate resultList
+ resultList = new QtNodeList();
+
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ {
+ if( input )
+ {
+ QtNodeList* subList = input->getChilds( flag );
+
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ }
+
+ if( updateTarget )
+ {
+ QtNodeList* subList = updateTarget->getChilds( flag );
+
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ }
+
+ if( updateDomain )
+ {
+ QtNodeList* subList = updateDomain->getChilds( flag );
+
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ }
+
+ if( updateSource )
+ {
+ QtNodeList* subList = updateSource->getChilds( flag );
+
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ }
+ };
+
+ // add the nodes of the current level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ {
+ resultList->push_back( input );
+ resultList->push_back( updateTarget );
+ resultList->push_back( updateDomain );
+ resultList->push_back( updateSource );
+ }
+
+ return resultList;
+}
+
+
+
+void
+QtUpdate::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtUpdate Object" << endl;
+
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ {
+ if( updateTarget )
+ {
+ s << SPACE_STR(tab).c_str() << "target: " << endl;
+ updateTarget->printTree( tab + 2, s );
+
+ if( updateDomain )
+ {
+ s << SPACE_STR(tab+2).c_str() << "domain: " << endl;
+ updateDomain->printTree( tab + 4, s );
+ }
+ else
+ s << SPACE_STR(tab+2).c_str() << "no domain" << endl;
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no target" << endl;
+
+ if( updateSource )
+ {
+ s << SPACE_STR(tab).c_str() << "source: " << endl;
+ updateSource->printTree( tab + 2, s );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no source" << endl;
+
+ if( input )
+ {
+ s << SPACE_STR(tab).c_str() << "input: " << endl;
+ input->printTree( tab+2, s, mode );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no input" << endl;
+
+ s << endl;
+ }
+}
+
+
+
+void
+QtUpdate::printAlgebraicExpression( ostream& s )
+{
+ s << "update<" << std::flush;
+
+ if( updateTarget )
+ updateTarget->printAlgebraicExpression( s );
+ else
+ s << "<no target>";
+
+ if( updateDomain )
+ updateDomain->printAlgebraicExpression( s );
+
+ s << "," << std::flush;
+
+ if( updateSource )
+ updateSource->printAlgebraicExpression( s );
+ else
+ s << "<no source>";
+
+ s << ">" << std::flush;
+
+ if( input )
+ {
+ s << "( ";
+ input->printAlgebraicExpression( s );
+ s << " )";
+ }
+ else
+ s << "(<no input>)" << std::flush;
+}
+
+
+
+void
+QtUpdate::setStreamInput( QtONCStream* newInput )
+{
+ input = newInput;
+ input->setParent( this );
+};
+
+QtOperation*
+QtUpdate::getUpdateTarget()
+{
+ return updateTarget;
+}
+
+QtOperation*
+QtUpdate::getUpdateDomain()
+{
+ return updateDomain;
+}
+
+QtOperation*
+QtUpdate::getUpdateSource()
+{
+ return updateSource;
+}
+
+QtONCStream*
+QtUpdate::getInput()
+{
+ return input;
+}
+
+/*
+void
+QtUpdate::preOptimize()
+{
+ if( updateTarget )
+ updateTarget->optimizeLoad( new QtNode::QtTrimList );
+
+ if( updateDomain )
+ updateDomain->optimizeLoad( new QtNode::QtTrimList );
+
+ if( updateSource )
+ updateSource->optimizeLoad( new QtNode::QtTrimList );
+
+ if( input )
+ input->preOptimize();
+}
+*/
+
+
+void
+QtUpdate::checkType()
+{
+ RMDBCLASS( "QtUpdate", "checkType()", "qlparser", __FILE__, __LINE__ )
+
+ // check operand branches
+ if( updateTarget && updateSource && input )
+ {
+
+ // get input type
+ QtTypeTuple inputType = input->checkType();
+
+ // check target
+ const QtTypeElement& targetType = updateTarget->checkType( &inputType );
+ if( targetType.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtUpdate::checkType() - update target must be an iterator variable." << endl;
+ parseInfo.setErrorNo(950);
+ throw parseInfo;
+ }
+
+ // check domain
+ if( updateDomain )
+ {
+ const QtTypeElement& domainType = updateDomain->checkType( &inputType );
+ if( domainType.getDataType() != QT_MINTERVAL )
+ {
+ RMInit::logOut << "Error: QtUpdate::checkType() - update domain must be of type Minterval." << endl;
+ parseInfo.setErrorNo(961);
+ throw parseInfo;
+ }
+ }
+
+ // check source
+ const QtTypeElement& sourceType = updateSource->checkType( &inputType );
+ if( sourceType.getDataType() != QT_MDD )
+ {
+ RMInit::logOut << "Error: QtUpdate::checkType() - update source must be an expression resulting in an MDD." << endl;
+ parseInfo.setErrorNo(951);
+ throw parseInfo;
+ }
+
+ // test for compatible base types
+ bool compatible = false;
+ char* type1 = ((MDDBaseType*)(targetType.getType()))->getBaseType()->getTypeStructure();
+ char* type2 = ((MDDBaseType*)(sourceType.getType()))->getBaseType()->getTypeStructure();
+ compatible = (strcmp(type1, type2) == 0);
+ free(type1);
+ free(type2);
+ type1 = NULL;
+ type2 = NULL;
+
+ if( !compatible )
+ {
+ RMInit::logOut << "Error: QtUpdate::checkType() - update base type does not match mdd base type." << endl;
+ parseInfo.setErrorNo(952);
+ throw parseInfo;
+ }
+ }
+ else
+ RMInit::logOut << "Error: QtUpdate::checkType() - operand branch invalid." << endl;
+}
+
+
+
+
+
diff --git a/qlparser/qtupdate.hh b/qlparser/qtupdate.hh
new file mode 100644
index 0000000..429a6e2
--- /dev/null
+++ b/qlparser/qtupdate.hh
@@ -0,0 +1,119 @@
+#ifndef __QTUPDATE_HH__
+#define __QTUPDATE_HH___
+
+#include "qlparser/qtexecute.hh"
+#include "qlparser/qtoncstream.hh"
+#include "qlparser/qtoperation.hh"
+
+#include <iostream>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+*/
+
+class QtUpdate : public QtExecute
+{
+ public:
+ /// constructor getting target, domain, and source expressions of the update
+ QtUpdate( QtOperation* initUpdateTarget, QtOperation* initUpdateDomain, QtOperation* initUpdateSource );
+
+ /// virtual destructor
+ virtual ~QtUpdate();
+
+ /// method for evaluating the node
+ virtual int evaluate();
+
+ /// return childs of the node
+ virtual QtNodeList* getChilds( QtChildType flag );
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ ///
+ void setStreamInput( QtONCStream* newInput );
+ ///
+ /// returns updateTarget
+ QtOperation* getUpdateTarget();
+ /// returns updateDomain
+ QtOperation* getUpdateDomain();
+ ///returns updateSource
+ QtOperation* getUpdateSource();
+ ///returns input
+ QtONCStream* getInput();
+ //@}
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// method for query rewrite
+ inline virtual void setInput( QtOperation* child, QtOperation* input);
+
+ /// pre optimization
+ //virtual void preOptimize();
+ /**
+ Pre-Optimization step is passed to the input streams.
+ */
+
+ /// type checking
+ virtual void checkType();
+
+ private:
+ /// one input stream
+ QtONCStream* input;
+
+ /// target expression
+ QtOperation* updateTarget;
+
+ /// target domain expression
+ QtOperation* updateDomain;
+
+ /// target expression
+ QtOperation* updateSource;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtupdate.icc"
+
+#endif
+
+
+
diff --git a/qlparser/qtupdate.icc b/qlparser/qtupdate.icc
new file mode 100644
index 0000000..5b98b0e
--- /dev/null
+++ b/qlparser/qtupdate.icc
@@ -0,0 +1,65 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtUpdate::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline void
+QtUpdate::setInput( QtOperation* inputOld, QtOperation* inputNew )
+{
+ if( inputOld == updateTarget )
+ {
+ updateTarget = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+
+ if( inputOld == updateDomain )
+ {
+ updateDomain = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+
+ if( inputOld == updateSource )
+ {
+ updateSource = inputNew;
+
+ if( inputNew )
+ inputNew->setParent( this );
+ }
+};
+
+
diff --git a/qlparser/qtvariable.cc b/qlparser/qtvariable.cc
new file mode 100644
index 0000000..730ad16
--- /dev/null
+++ b/qlparser/qtvariable.cc
@@ -0,0 +1,392 @@
+/*
+* 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, QtVariable: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtvariable.cc,v 1.24 2003/12/27 20:40:52 rasdev Exp $";
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+using namespace std;
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtvariable.hh"
+#include "qlparser/qtmdd.hh"
+
+#include "mddmgr/mddobj.hh"
+
+
+const QtNode::QtNodeType QtVariable::nodeType = QT_MDD_VAR;
+
+
+QtVariable::QtVariable( const string& initName )
+ : iteratorName( initName ),
+ loadDomain(),
+ oldLoadDomain(),
+ dataIndex(-1)
+{
+ domainFlag = new vector<bool>();
+}
+
+
+QtVariable::QtVariable( const string& initName, const r_Minterval& initDomain )
+ : iteratorName( initName ),
+ loadDomain( initDomain ),
+ oldLoadDomain(),
+ dataIndex(-1)
+{
+ domainFlag = new vector<bool>();
+}
+
+
+QtVariable::~QtVariable()
+{
+ // delete STL vector including its elements
+ delete domainFlag;
+ domainFlag=NULL;
+}
+
+
+bool
+QtVariable::equalMeaning( QtNode* node )
+{
+ RMDBCLASS( "QtVariable", "equalMeaning( QtNode* )", "qlparser", __FILE__, __LINE__ )
+
+ bool result = false;
+
+ if( nodeType == node->getNodeType() )
+ {
+ QtVariable* mddVarNode;
+
+ mddVarNode = (QtVariable*) node; // by force
+
+ if( iteratorName.compare ( mddVarNode->getIteratorName()) == 0 )
+ if( ( loadDomain.dimension() == 0 ) ||
+ ( (mddVarNode->getLoadDomain()).dimension() == 0 ) )
+ result = true;
+ else
+ if( loadDomain.dimension() == (mddVarNode->getLoadDomain()).dimension() )
+ result = loadDomain.intersects_with( mddVarNode->getLoadDomain() );
+ };
+
+ // equalMeaning() depends only on the loadDomain and not on the domainFlag!
+
+ return result;
+}
+
+
+string
+QtVariable::getSpelling()
+{
+ r_Point point;
+ r_Dimension d;
+
+ char tempStr[20];
+ ostringstream os;
+ sprintf(tempStr, "%ud", (unsigned long)getNodeType());
+ string result = string(tempStr);
+
+ result.append( iteratorName );
+
+ if( loadDomain.dimension() > 0)
+ {
+ os << loadDomain << ends;
+ result.append(os.str());
+ };
+
+ return result;
+}
+
+
+QtNode::QtAreaType
+QtVariable::getAreaType()
+{
+ return QT_AREA_MDD;
+}
+
+
+void
+QtVariable::optimizeLoad( QtTrimList* trimList )
+{
+ RMDBCLASS( "QtVariable", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
+
+ if( !trimList->empty() )
+ {
+ // get the highest specified dimension
+ r_Dimension maxDimension=0;
+ QtTrimList::iterator i;
+
+ for( i=trimList->begin(); i!=trimList->end(); i++ )
+ // get the maximum
+ maxDimension = maxDimension > (*i)->dimension ? maxDimension : (*i)->dimension;
+
+ // create a new loadDomain object and initialize it with open bounds
+ loadDomain = r_Minterval(maxDimension+1);
+
+ delete domainFlag; // delete the old array
+ domainFlag = new vector<bool>(maxDimension+1);
+
+ for( int j=0; j<loadDomain.dimension(); j++ )
+ {
+ loadDomain[j] = r_Sinterval('*','*');
+ (*domainFlag)[j] = true;
+ }
+
+ // fill the loadDomain object with the QtTrimList specifications
+ for( i=trimList->begin(); i!=trimList->end(); i++ )
+ {
+ loadDomain[(*i)->dimension] = (*i)->interval;
+ (*domainFlag)[(*i)->dimension] = (*i)->intervalFlag;
+ }
+
+ // delete heap based elements
+ // release( trimList->begin(), trimList->end() );
+ for( QtNode::QtTrimList::iterator iter=trimList->begin(); iter!=trimList->end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+
+ // changed from RMInit:logOut -- PB 2003-nov-20
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtVariable", "optimizeLoad: geometric load optimization: " << iteratorName << loadDomain );
+ }
+
+ // delete list
+ delete trimList;
+ trimList=NULL;
+}
+
+
+
+QtData*
+QtVariable::evaluate( QtDataList* inputList ) throw (ParseInfo)
+{
+ RMDBCLASS( "QtVariable", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
+
+ RMDBGENTER( 2, RMDebug::module_qlparser, "QtVariable", "QtVariable::evaluate() - " << iteratorName.c_str() << endl )
+
+ vector<QtData*>::iterator i; //default
+
+ QtData* returnValue = NULL;
+
+ if( inputList /* && inputList->size() > dataIndex*/ )
+ {
+ QtData* dataObject = 0;
+
+ if( dataIndex == -1 )
+ {
+ // Search for the data object matching the iterator name
+ int pos = 0;
+
+ for( QtDataList::iterator iter=inputList->begin(); iter!=inputList->end() && !dataObject; iter++ )
+ {
+ if( iteratorName == (*iter)->getIteratorName() )
+ dataObject = *iter;
+ else
+ pos++;
+ }
+
+ if( dataObject ) dataIndex = pos;
+ }
+ else
+ // For performance reasons, take the data element from position determined in the first run.
+ dataObject = (*inputList)[dataIndex];
+
+ if( !dataObject )
+ {
+ RMInit::logOut << "Error: QtVariable::evaluate() - collection iterator " <<
+ iteratorName.c_str() << " is unknwon." << endl;
+ parseInfo.setErrorNo(357);
+ throw parseInfo;
+ }
+
+ if( dataObject->getDataType() == QT_MDD )
+ {
+ if( loadDomain.dimension() == 0 )
+ {
+ // If no domain is specified, the load domain equals the current domain.
+ // This means that the data object is passed with an incremented reference.
+ // This mainly occurs with point accesses.
+
+ dataObject->incRef();
+ returnValue = dataObject;
+ }
+ else
+ {
+ QtMDD* qtMDD = (QtMDD*)dataObject;
+ MDDObj* currentMDDObj = qtMDD->getMDDObject();
+
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtVariable", " definitionDomain: " << currentMDDObj->getDefinitionDomain() )
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtVariable", " currentDomain...: " << currentMDDObj->getCurrentDomain() )
+
+ // load domain for the actual MDDObj
+ r_Minterval actLoadDomain;
+
+ // intersect actLoadDomain with defined domain
+ try{
+ actLoadDomain.intersection_of( loadDomain, currentMDDObj->getCurrentDomain() );
+ }
+ catch( r_Edim_mismatch& )
+ {
+ RMInit::logOut << "Error: QtVariable::evaluate() - specified domain dimensionality does not equal defined dimensionality." << endl;
+ parseInfo.setErrorNo(362);
+ throw parseInfo;
+ }
+ catch( r_Eno_interval )
+ {
+ RMInit::logOut << "Error: QtVariable::evaluate() - Specified domain does not intersect with spatial domain of MDD." << endl;
+ parseInfo.setErrorNo(356);
+ throw parseInfo;
+ }
+ catch( r_Error& err )
+ {
+ RMInit::logOut << "Error: QtVariable::evaluate() - general error." << endl;
+ parseInfo.setErrorNo(350);
+ throw parseInfo;
+ }
+
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtVariable", " loadDomain......: " << actLoadDomain )
+
+ if( qtMDD->getLifetime() == QtData::QT_PERSISTENT )
+ {
+ //
+ // Create a new QtMDD object as carrier object for the persistent MDD object
+ // and attach the load domain. Now there are more than one MDD objects pointing
+ // to the same persistent MDD object which should not cause any problem.
+ //
+ // Note: Taking the same MDD object would mean sharing also the load domain which
+ // is not possible if the iterator variable occurs with different spatial operations.
+ //
+
+ QtMDD* result = new QtMDD( (MDDObj*)currentMDDObj );
+ result->setLoadDomain( actLoadDomain );
+
+ returnValue = result;
+ }
+ else
+ {
+ // Take the transient data object and increase its reference.
+ //
+ // Note: For a transient MDD object just one QtMDD carrier object is allowed.
+
+ qtMDD->incRef();
+ returnValue = qtMDD;
+ }
+
+ }
+
+ }
+ else
+ {
+ // Take the atomic data object and increase its reference.
+ dataObject->incRef();
+ returnValue = dataObject;
+ }
+
+ }
+ else
+ {
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QtVariable", "Error: QtVariable::evaluate() - the input list is empty." )
+ }
+ return returnValue;
+}
+
+
+void
+QtVariable::printTree( int tab, ostream& s, QtChildType /*mode*/ )
+{
+ s << SPACE_STR(tab).c_str() << "QtVariable Object: type " << flush;
+ dataStreamType.printStatus( s );
+ s << " name |" << iteratorName.c_str() << "|" /* << " pos " << dataIndex */ << endl;
+
+ if( loadDomain.dimension() > 0 )
+ {
+ s << SPACE_STR(tab).c_str() << "load domain: ";
+ loadDomain.print_status( s );
+ s << " - Trimflag: ";
+
+ for( int i=0; i<domainFlag->size(); i++)
+ s << (*domainFlag)[i];
+ s << endl;
+ }
+
+ if( oldLoadDomain.dimension() > 0 )
+ {
+ s << SPACE_STR(tab).c_str() << "old domain: ";
+ oldLoadDomain.print_status( s );
+ s << endl;
+ };
+}
+
+
+
+void
+QtVariable::printAlgebraicExpression( ostream& s )
+{
+ s << iteratorName.c_str() << flush;
+}
+
+
+
+const QtTypeElement&
+QtVariable::checkType( QtTypeTuple* typeTuple ) throw (ParseInfo)
+{
+ RMDBCLASS( "QtVariable", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
+
+ dataStreamType.setDataType( QT_TYPE_UNKNOWN );
+
+ if( typeTuple )
+ {
+ vector<QtTypeElement>::iterator iter;
+
+ // search for the type matching the variable name
+ for( iter=typeTuple->tuple.begin();
+ iter!=typeTuple->tuple.end() && dataStreamType.getDataType() == QT_TYPE_UNKNOWN;
+ iter++ )
+ {
+ if( (*iter).getName() && iteratorName == string( (*iter).getName() ) )
+ dataStreamType = *iter;
+ }
+ }
+
+ if( (dataStreamType.getDataType() == QT_TYPE_UNKNOWN) )
+ {
+ RMInit::logOut << "Error: QtVariable::checkType() - variable " << iteratorName.c_str() << " is unknwon." << endl;
+ parseInfo.setErrorNo(357);
+ throw parseInfo;
+ }
+
+ return dataStreamType;
+}
+
+
+
diff --git a/qlparser/qtvariable.hh b/qlparser/qtvariable.hh
new file mode 100644
index 0000000..f056da7
--- /dev/null
+++ b/qlparser/qtvariable.hh
@@ -0,0 +1,136 @@
+#ifndef _QTVARIABLE_
+#define _QTVARIABLE_
+
+#include "qlparser/qtoperation.hh"
+#include "raslib/minterval.hh"
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+
+#include <stdio.h>
+
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+ //@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ The class stands for a MDD variable which corresponds to an element of the
+ tupel passed by the evaluate() method.
+
+*/
+
+
+class QtVariable : public QtOperation
+{
+ public:
+ /// constructor getting iterator variable name
+ QtVariable( const std::string& iteratorName );
+
+ /// constructor getting iterator variable name and load domain
+ QtVariable( const std::string& iteratorName, const r_Minterval& loadDomain );
+
+ /// destructor
+ virtual ~QtVariable();
+
+ /// test if the two nodes have an equal meaning in the query tree
+ virtual bool equalMeaning( QtNode* node );
+
+ /// creates a unique name for a common subexpression
+ virtual std::string getSpelling();
+
+ /// test if the edge to the parent node is of type mdd or atomic
+ virtual QtAreaType getAreaType();
+
+ /// optimizing load access
+ void optimizeLoad( QtTrimList* trimList );
+
+ /// method for evaluating the node
+ QtData* evaluate( QtDataList* inputList ) throw (ParseInfo);
+
+ /// prints the tree
+ virtual void printTree( int tab, std::ostream& s = std::cout, QtChildType mode = QT_ALL_NODES );
+
+ /// prints the algebraic expression
+ virtual void printAlgebraicExpression( std::ostream& s = std::cout );
+
+ /// methods for iterator name
+ inline const std::string getIteratorName() const;
+ inline void setIteratorName( std::string& str );
+
+ /// method for loadDomain
+ inline const r_Minterval getLoadDomain() const;
+
+ /// method for loadDomain
+ inline void setLoadDomain( r_Minterval& loadDomain );
+
+ /// method for oldLoadDomain
+ inline void setOldLoadDomain();
+
+ /// method for oldLoadDomain
+ inline const r_Minterval getOldLoadDomain();
+
+ /// method for LoadDomain
+ inline vector<bool>* getLoadDomainFlag();
+
+ /// method for identification of nodes
+ inline virtual const QtNodeType getNodeType() const;
+
+ /// type checking of the subtree
+ virtual const QtTypeElement& checkType( QtTypeTuple* typeTuple = NULL ) throw (ParseInfo);
+
+ private:
+
+ /// attribute storing the iterator name
+ std::string iteratorName;
+
+ /// minterval storing the minimal domain which is needed in the upper tree
+ r_Minterval loadDomain;
+
+ /// unique backup of the loadDomain
+ r_Minterval oldLoadDomain;
+
+ /// bitvector for discrimination of trimming and projections
+ vector<bool>* domainFlag;
+
+ /// attribute storing the index of the variable's data element in the data vector
+ int dataIndex;
+
+ /// attribute for identification of nodes
+ static const QtNodeType nodeType;
+};
+
+#include "qlparser/qtvariable.icc"
+
+#endif
+
diff --git a/qlparser/qtvariable.icc b/qlparser/qtvariable.icc
new file mode 100644
index 0000000..0625b32
--- /dev/null
+++ b/qlparser/qtvariable.icc
@@ -0,0 +1,84 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline const QtNode::QtNodeType
+QtVariable::getNodeType() const
+{
+ return nodeType;
+}
+
+
+inline const std::string
+QtVariable::getIteratorName() const
+{
+ return iteratorName;
+}
+
+inline void
+QtVariable::setIteratorName( std::string& str )
+{
+ iteratorName = str;
+}
+
+
+inline const r_Minterval
+QtVariable::getLoadDomain() const
+{
+ return loadDomain;
+}
+
+
+inline void
+QtVariable::setLoadDomain( r_Minterval& loadDomainNew )
+{
+ if( oldLoadDomain.dimension() == 0 )
+ oldLoadDomain = loadDomain;
+ loadDomain = loadDomainNew;
+}
+
+
+inline void
+QtVariable::setOldLoadDomain()
+{
+ loadDomain = oldLoadDomain;
+}
+
+
+inline const r_Minterval
+QtVariable::getOldLoadDomain()
+{
+ return oldLoadDomain;
+}
+
+
+inline std::vector<bool>*
+QtVariable::getLoadDomainFlag()
+{
+ return domainFlag;
+}
diff --git a/qlparser/querytree.cc b/qlparser/querytree.cc
new file mode 100644
index 0000000..4a14ed6
--- /dev/null
+++ b/qlparser/querytree.cc
@@ -0,0 +1,489 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ * SOURCE: querytree.cc
+ *
+ * MODULE: qlparser
+ * CLASS: QueryTree
+ *
+ * PURPOSE:
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, QueryTree: $Id: querytree.cc,v 1.52 2005/06/28 08:42:13 rasdev Exp $";
+
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+using namespace std;
+#endif
+#include <iostream>
+#include <dlfcn.h>
+
+#include "raslib/rmdebug.hh"
+#include "globals.hh"
+
+#include "qlparser/querytree.hh"
+#include "qlparser/qtnode.hh"
+#include "qlparser/qtoperationiterator.hh"
+#include "qlparser/qtselectioniterator.hh"
+#include "qlparser/qtjoiniterator.hh"
+#include "qlparser/qtvariable.hh"
+#include "qlparser/qtmdd.hh"
+#include "qlparser/qtdomainoperation.hh"
+#include "qlparser/qtexecute.hh"
+
+#include "catalogmgr/typefactory.hh"
+#include "relcatalogif/mdddomaintype.hh"
+#include "relcatalogif/settype.hh"
+
+void (*QueryTree::optimizationFnc)(unsigned int, QtNode*) = NULL;
+
+unsigned int QueryTree::nextCSENo = 0;
+
+SymbolTable<int> QueryTree::symtab;
+
+QueryTree::QueryTree()
+ : rootNode(NULL),
+ optimizationLevel(4)
+{
+}
+
+
+QueryTree::QueryTree( QtNode* root )
+ : rootNode( root ),
+ optimizationLevel(4)
+{
+}
+
+
+QueryTree::~QueryTree()
+{
+ if( rootNode )
+ {
+ delete rootNode;
+ rootNode=NULL;
+ }
+ releaseDynamicObjects();
+}
+
+
+void
+QueryTree::checkSemantics()
+{
+ RMDBCLASS( "QueryTree", "checkSemantics()", "qlparser", __FILE__, __LINE__ )
+
+ switch( rootNode->getNodeType() )
+ {
+ case QtNode::QT_MDD_ACCESS:
+ case QtNode::QT_OPERATION_ITERATOR:
+ case QtNode::QT_JOIN_ITERATOR:
+ case QtNode::QT_SELECTION_ITERATOR:
+ {
+ const QtTypeTuple& resultType = ((QtONCStream*)rootNode)->checkType();
+ // RMInit::logOut << "result type: " << flush;
+ // resultType.printStatus( RMInit::logOut );
+ }
+ break;
+
+ case QtNode::QT_UPDATE:
+ case QtNode::QT_INSERT:
+ case QtNode::QT_DELETE:
+ case QtNode::QT_COMMAND:
+ case QtNode::QT_PYRAMID:
+ ((QtExecute*)rootNode)->checkType();
+ break;
+
+ default:
+ {
+ const QtTypeElement& resultType = ((QtOperation*)rootNode)->checkType();
+ // RMInit::logOut << "result type: " << flush;
+ // resultType.printStatus( RMInit::logOut );
+ }
+ break;
+ }
+}
+
+
+void
+QueryTree::optimize( unsigned int currentOptimizationLevel )
+{
+ RMDBCLASS( "QueryTree", "optimize( unsigned int )", "qlparser", __FILE__, __LINE__ )
+
+ if (optimizationFnc == NULL) {
+ char *dir = CONFDIR;
+ char libName[255];
+ sprintf(libName,"%s/lib/libqloptimizer.so", dir);
+
+ if (access(libName, X_OK | R_OK) == 0) {
+ void *handle = dlopen(libName, RTLD_NOW);
+ if (handle == NULL) {
+ RMInit::logOut << "Optimization library found, however could not be loaded" << endl;
+ printf("DLERROR = %s\n", dlerror());
+ RMInit::logOut << dlerror() << endl;
+ return;
+ }
+
+ *(void **)(&optimizationFnc) = dlsym(handle, "runOptimizations");
+ if (optimizationFnc == NULL) {
+ RMInit::logOut << "Optimization library found, however the entry point was not found" << endl;
+ return;
+ }
+ } else {
+ RMInit::logOut << "No optimization library found" << endl;
+ return;
+ }
+ }
+
+ optimizationFnc(currentOptimizationLevel, rootNode);
+
+ RMDBGIF( 1, RMDebug::module_qlparser, "QueryTree", \
+ RMInit::logOut << endl << " "; \
+ rootNode->printAlgebraicExpression( RMInit::logOut ); \
+ RMInit::logOut << endl << endl; \
+ rootNode->printTree( 2, RMInit::logOut ); \
+ RMInit::logOut << endl; \
+ )
+}
+
+vector<QtData*>*
+QueryTree::evaluateRetrieval() throw (r_Error, ParseInfo)
+{
+ vector<QtData*>* returnValue=NULL;
+
+ if( rootNode )
+ {
+ if( rootNode->getNodeType() != QtNode::QT_MDD_ACCESS &&
+ rootNode->getNodeType() != QtNode::QT_OPERATION_ITERATOR &&
+ rootNode->getNodeType() != QtNode::QT_JOIN_ITERATOR &&
+ rootNode->getNodeType() != QtNode::QT_SELECTION_ITERATOR )
+ {
+ RMInit::logOut << "QueryTree::evaluateRetrieval() - Retrieval query must start with an ONC node." << endl;
+ ParseInfo errorInfo = rootNode->getParseInfo();
+ errorInfo.setErrorNo(371);
+ throw errorInfo;
+ }
+
+ QtNode::QtDataList* dataList=NULL;
+ QtNode::QtDataList::iterator dataIter;
+ QtONCStream* oncRootNode = (QtONCStream*)rootNode;
+
+ try
+ {
+ oncRootNode->open();
+ }
+ catch( ... )
+ {
+ oncRootNode->close();
+ RMInit::logOut << "QueryTree::evaluateRetrieval() - rethrow exception from oncRootNode->open()." << endl;
+ throw;
+ }
+
+ // removed to have uniform, compact log output -- PB 2003-nov-20
+ // RMInit::logOut << endl;
+
+ // create result collection
+ vector<QtData*>* resultData = new vector<QtData*>();
+
+ try
+ {
+ while( (dataList = oncRootNode->next()) )
+ {
+ if( dataList->size() > 1 || (*dataList)[0] == NULL )
+ {
+ // Delete the tupel vector received by next(). Just tupel elements which are not
+ // further referenced are deleted.
+ for( dataIter=dataList->begin(); dataIter!=dataList->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete dataList;
+ dataList=NULL;
+
+ if( resultData )
+ {
+ // Delete the result vector
+ for( dataIter=resultData->begin(); dataIter!=resultData->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete resultData;
+ resultData = NULL;
+ }
+
+ RMInit::logOut << "QueryTree::evaluateTree() - multiple query targets are not supported." << endl;
+ ParseInfo errorInfo = oncRootNode->getParseInfo();
+ errorInfo.setErrorNo(361);
+ throw errorInfo;
+ }
+
+ QtData* resultElement = (*dataList)[0];
+
+ // take the data element as result data and reset it in the tupel vector
+ resultData->push_back( resultElement );
+ (*dataList)[0] = NULL;
+
+ RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QueryTree", endl << endl << "NEXT RESULT ITEM OF THE QUERY INSERTED" << endl << endl )
+
+ // Delete the tupel vector received by next(). Just tupel elements which are not
+ // set to zero and which are not further referenced are deleted.
+ for( dataIter=dataList->begin(); dataIter!=dataList->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+
+ // delete the tuple vector
+ delete dataList;
+ dataList=NULL;
+ }
+ }
+ catch(r_Error& myErr) {
+ RMInit::logOut << endl << "Caught BAD exception when evaluating query! " << endl;
+ RMInit::logOut << myErr.what() << endl;
+ if( resultData )
+ {
+ // Delete the result vector
+ for( dataIter=resultData->begin(); dataIter!=resultData->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete resultData;
+ resultData = NULL;
+ }
+
+ oncRootNode->close();
+ RMInit::logOut << "QueryTree::evaluateTree() - rethrow exception." << endl;
+ throw;
+ }
+ catch( ... )
+ {
+ if( resultData )
+ {
+ // Delete the result vector
+ for( dataIter=resultData->begin(); dataIter!=resultData->end(); dataIter++ )
+ if( *dataIter ) (*dataIter)->deleteRef();
+ delete resultData;
+ resultData = NULL;
+ }
+
+ oncRootNode->close();
+ RMInit::logOut << "QueryTree::evaluateTree() - rethrow exception." << endl;
+ throw;
+ }
+
+ oncRootNode->close();
+
+ returnValue = resultData;
+ }
+
+ return returnValue;
+}
+
+
+
+void
+QueryTree::evaluateUpdate() throw (r_Error,ParseInfo)
+{
+ if( rootNode )
+ {
+ if( rootNode->getNodeType() != QtNode::QT_UPDATE &&
+ rootNode->getNodeType() != QtNode::QT_INSERT &&
+ rootNode->getNodeType() != QtNode::QT_DELETE &&
+ rootNode->getNodeType() != QtNode::QT_COMMAND &&
+ rootNode->getNodeType() != QtNode::QT_PYRAMID
+ )
+ {
+ RMInit::logOut << "QueryTree::evaluateUpdate() - update query must start with an INSERT, UPDATE, DELETE, DROP or CREATE statement." << endl;
+ ParseInfo errorInfo = rootNode->getParseInfo();
+ errorInfo.setErrorNo(372);
+ throw errorInfo;
+ }
+
+ QtExecute* executeNode = (QtExecute*) rootNode;
+
+ // evaluate the update query
+ executeNode->evaluate();
+ }
+}
+
+
+
+void QueryTree::printTree( int tab, ostream& s ) {
+ if ( rootNode ) {
+ s << SPACE_STR(tab).c_str() << "QueryTree:" << endl;
+ rootNode->printTree( tab + 2, s );
+ } else
+ s << SPACE_STR(tab).c_str() << "QueryTree: Qt has no root node." << endl;
+}
+
+void QueryTree::addDynamicObject( QtNode *node ) {
+ qtNodeList.push_back( node );
+}
+
+void QueryTree::removeDynamicObject( QtNode *node ) {
+ qtNodeList.remove( node );
+}
+
+void QueryTree::addDynamicObject( QtData *node ) {
+ qtDataList.push_back( node );
+}
+
+void QueryTree::removeDynamicObject( QtData *node ) {
+ qtDataList.remove( node );
+}
+
+void QueryTree::addDynamicObject( ParseInfo *node ) {
+ parseInfoList.push_back( node );
+}
+
+void QueryTree::removeDynamicObject( ParseInfo *node ) {
+ parseInfoList.remove( node );
+}
+
+void QueryTree::addDynamicObject( vector<QtONCStream *> *node ) {
+ vectorList.push_back( node );
+}
+
+void QueryTree::removeDynamicObject( vector<QtONCStream*> *node ) {
+ vectorList.remove( node );
+}
+
+void QueryTree::releaseDynamicObjects() {
+ list<QtNode*>::iterator iter1;
+ for( iter1 = qtNodeList.begin(); iter1 != qtNodeList.end(); iter1++ )
+ {
+ delete *iter1;
+ *iter1=NULL;
+ }
+
+ list<QtData*>::iterator iter2;
+ for( iter2 = qtDataList.begin(); iter2 != qtDataList.end(); iter2++ )
+ {
+ delete *iter2;
+ *iter2=NULL;
+ }
+
+ list<ParseInfo*>::iterator iter3;
+ for( iter3 = parseInfoList.begin(); iter3 != parseInfoList.end(); iter3++ )
+ {
+ delete *iter3;
+ *iter3=NULL;
+ }
+
+ list<vector<QtONCStream*>*>::iterator iter4;
+ for( iter4 = vectorList.begin(); iter4 != vectorList.end(); iter4++ )
+ {
+ delete *iter4;
+ *iter4=NULL;
+ }
+
+ list<char *>::iterator iter5;
+ for( iter5 = lexedCStringList.begin(); iter5 != lexedCStringList.end(); iter5++ )
+ {
+ free(*iter5);
+ *iter5=NULL;
+ }
+}
+
+void QueryTree::addDomainObject( QtDomainOperation *dop ) {
+ dopList.push_back( dop );
+}
+
+void QueryTree::removeDomainObject( QtDomainOperation *dop ) {
+ dopList.remove( dop );
+}
+
+void QueryTree::printDomainObjects() {
+ list<QtDomainOperation*>::iterator iter;
+ for( iter = dopList.begin(); iter != dopList.end(); iter++ ) {
+ cout << endl;
+ (*iter)->printTree( 2 );
+ }
+}
+
+void QueryTree::releaseDomainObjects() {
+ list<QtDomainOperation*>::iterator iter;
+ for( iter = dopList.begin(); iter != dopList.end(); iter++ )
+ {
+ delete *iter;
+ *iter=NULL;
+ }
+}
+
+void QueryTree::rewriteDomainObjects(r_Minterval *greatDomain, string *greatIterator, QtMarrayOp2::mddIntervalListType *greatList) {
+
+ RMDBGENTER( 2, RMDebug::module_qlparser, "QueryTree", endl << "QueryTree: Iterator: <" << *greatIterator << "> Domain: " << *greatDomain << endl )
+ list<QtDomainOperation*>::iterator iter;
+
+ for( iter = dopList.begin(); iter != dopList.end(); iter++ ) {
+
+ // 1. get var name from iter
+ QtVariable *qtVar = ((QtVariable *)((*iter)->getInput()));
+ string stVar = qtVar->getIteratorName();
+ const char *varname = stVar.c_str();
+
+ // 2. get position of varname in varList
+ bool bcond = false;
+ QtMarrayOp2::mddIntervalListType *varList = greatList;
+ QtMarrayOp2::mddIntervalListType::iterator varIter;
+ r_Long varpos = 0;
+ for (varIter = varList->begin(); varIter != varList->end(); varIter++) {
+
+ if (!strcmp(varname, varIter->variable.c_str())) {
+ bcond = true;
+ break;
+ };
+ QtData *data = varIter->tree->evaluate(0);
+ r_Dimension dimension = ((QtMintervalData*)data)->getMintervalData().dimension();
+ varpos = varpos+dimension;
+ };
+ // postcond: bcond == false: varname not found in list. else varpos gives the position.
+
+ if (bcond) {
+
+ // 3. set domain expression to old one incremented by varpos
+ QtNode::QtOperationList *lop = new QtNode::QtOperationList(1);
+ (*lop)[0] =
+ new QtPlus(
+ (*iter)->getMintervalOp(),
+ new QtConst(
+ new QtAtomicData(
+ varpos, sizeof(varpos)
+ )
+ )
+ );
+
+ (*iter)->setMintervalOp( new QtPointOp( lop ) );
+
+ // 4. set varname to greatIterator
+ QtVariable *var1 = new QtVariable( string(*greatIterator) );
+ (*iter)->setInput(var1);
+
+ } else
+ {
+ // TODO: insert some error notify code here!
+ RMDBGMIDDLE( 1, RMDebug::module_qlparser, "QueryTree", " variable name not found in list " )
+ }
+ }
+}
+
+void QueryTree::addCString( char *str ) {
+ lexedCStringList.push_back( str );
+}
diff --git a/qlparser/querytree.hh b/qlparser/querytree.hh
new file mode 100644
index 0000000..d6f28cc
--- /dev/null
+++ b/qlparser/querytree.hh
@@ -0,0 +1,265 @@
+/*
+* 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>.
+*/
+#ifndef _QUERYTREE_
+#define _QUERYTREE_
+
+#ifndef CPPSTDLIB
+#include <ospace/string.h> // STL<ToolKit>
+#else
+#include <string>
+#endif
+#include <algorithm>
+
+#include "mddmgr/mddcoll.hh"
+
+#include "qlparser/qtnode.hh"
+#include "qlparser/qtatomicdata.hh"
+#include "qlparser/qtbinaryinduce.hh"
+#include "qlparser/qtconst.hh"
+#include "qlparser/qtdomainoperation.hh"
+#include "qlparser/qtmarrayop2.hh"
+#include "qlparser/qtpointop.hh"
+#include "qlparser/symtab.hh"
+
+// forward declarations
+class MDDObj;
+class QtONCStream;
+class QtDomainOperation;
+
+
+/*************************************************************
+ *
+ *
+ * INCLUDE: querytree.hh
+ *
+ * MODULE: qlparser
+ * CLASS: QueryTree
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+The Query Tree is the internal representation of a RasML query string. It
+consists of instances of the above class hierarchy. The tree is created in
+the Query Parser Modul in the action sections of the yacc grammar. According
+to the parser semantics, the tree is built bottom up which means that the leaf
+objects are created first. They are given up via the parse stack. Inner objects
+get references to the subobjects after they are created. The whole tree is a
+dynamic data structure. The semantics is that if an object is deleted also its
+subobjects are deleted which means that the deletion of the root object cleans
+up the whole tree.
+
+The class QueryTree encapsulates a query tree consisting of suclasses of type
+QtNode. It consists of the entry point and methods working on the whole tree
+(e.g. traversing).
+
+*/
+
+class QueryTree
+{
+ public:
+
+
+ /// default constructor
+ QueryTree();
+
+ /// constructor getting the root of the query tree
+ QueryTree( QtNode* root );
+
+ /// destructor (deletes the whole query tree)
+ ~QueryTree();
+
+ /// checks semantics (e.g., type checking)
+ void checkSemantics();
+
+ /// optimizes the tree
+ void optimize( unsigned int optimizationLevel );
+
+ /*@Doc:
+ The method optimizes the query tree.
+ */
+
+ /// recognize common subexpressions
+ vector<QtNode::QtNodeList>* seeSubexpression();
+
+ /*@Doc:
+ The method returns a list of all common subexpressions in the query tree.
+ The private methods seeSubexpression(..) are used.
+ */
+
+ /// build in common subexpressions in the query tree
+ void insertSubexpression( vector<QtNode::QtNodeList>* nodeList );
+
+ /*@Doc:
+ The method manipulates the query tree to handle common subexpressions.
+ */
+
+ /// executes a retrieval tree and gives back the result collection
+ vector<QtData*>* evaluateRetrieval() throw (r_Error, ParseInfo);
+
+ /*@Doc:
+ The method evaluates a retrieval tree and returns the result collection. For this purpose,
+ first, the {\tt open()} message is sent to the root node of the tree. Then {\tt next()}
+ is invoked on the root node which, each time, returns one element of the result
+ collection. It indicates the end of the evaluation process through returning a null pointer.
+ At the end, {\tt close()} is called to clean up the ressources. If errors occur, various exceptions
+ are thrown.
+ */
+
+ /// executes an update tree and throws a ParseInfo if query does not begin with INSERT, DELETE, UPDATE, ...
+ void evaluateUpdate() throw (r_Error,ParseInfo);
+
+ /// debugging method
+ void printTree( int tab, ostream& s = cout );
+
+ //@Man: read/write methods
+ //@{
+ ///
+
+ ///
+ inline QtNode* getRoot() const;
+ ///
+ inline void setRoot( QtNode* root );
+ ///
+ inline void setOptimizationLevel( unsigned int level );
+ ///
+ inline unsigned int getOptimizationLevel();
+
+ ///
+ //@}
+
+ //@Man: methods used to maintain pointers to dynamic data structures used in the parse process
+ //@{
+ ///
+
+ ///
+ void addDynamicObject( QtNode* );
+ ///
+ void removeDynamicObject( QtNode* );
+ ///
+ void addDynamicObject( QtData* );
+ ///
+ void removeDynamicObject( QtData* );
+ ///
+ void addDynamicObject( ParseInfo* );
+ ///
+ void removeDynamicObject( ParseInfo* );
+ ///
+ void addDynamicObject( vector<QtONCStream*>* );
+ ///
+ void removeDynamicObject( vector<QtONCStream*>* );
+ ///
+ void releaseDynamicObjects();
+ ///
+ void addDomainObject( QtDomainOperation * );
+ ///
+ void removeDomainObject( QtDomainOperation * );
+ ///
+ void rewriteDomainObjects(r_Minterval *greatDomain, std::string *greatIterator, QtMarrayOp2::mddIntervalListType *greatList);
+ ///
+ void printDomainObjects();
+ ///
+ void releaseDomainObjects();
+ ///
+ void addCString( char * );
+ ///
+ //@}
+
+ ///
+ static SymbolTable<int> symtab;
+
+ private:
+ /// attribute storing the root of the query tree
+ QtNode* rootNode;
+
+ static void (*optimizationFnc)(unsigned int, QtNode*);
+
+ /// used by public seeSubexpression()
+ vector<QtNode::QtNodeList>* seeSubexpression( QtNode::QtNodeList* leafList );
+
+ /// used by public seeSubexpression()
+ QtNode::QtNodeList* seeSubexpression( QtNode::QtNodeList* leafList, vector<QtNode::QtNodeList>* leafListsNew );
+
+ /// level of optimization restricted for this query
+ unsigned int optimizationLevel;
+
+ /// attribute carrying next free number for CSE iterator
+ static unsigned int nextCSENo;
+
+ /// list of unlinked subtrees
+ std::list<QtNode*> qtNodeList;
+ /**
+ This list is used to store subtrees of type \Ref{QtNode} generated in the parse
+ process and not linked to the result tree yet. In case of an error
+ during the parse process, this list is freed.
+ */
+
+ /// list of unlinked subtrees
+ std::list<QtData*> qtDataList;
+ /**
+ This list is used to store subtrees of type \Ref{QtData} generated in the parse
+ process and not linked to the result tree yet. In case of an error
+ during the parse process, this list is freed.
+ */
+
+ /// list of unlinked subtrees
+ std::list<ParseInfo*> parseInfoList;
+ /**
+ This list is used to store elements of type \Ref{ParseInfo} generated in the parse
+ process and not linked to the result tree yet. In case of an error
+ during the parse process, this list is freed.
+ */
+
+ /// list of unlinked lists
+ std::list<vector<QtONCStream*>*> vectorList;
+ /**
+ This list is used to store elements of type \Ref{vector<QtONCStream*>} generated
+ in the parse process and not linked to the result tree yet. In case of an error
+ during the parse process, this list is freed.
+ */
+
+ /// list of domain operations relevant to variables in an MArray.
+ std::list<QtDomainOperation *> dopList; // contains basically QtDomainOperation (everything else is evil :-) )
+ /**
+ This list is used to store elements of type \Ref{QtDomainOperation *} generated
+ in the parse process for the purpose of a tree rewrite. In case of an error
+ during the parse process, this list is freed.
+ */
+
+ /// list of lexed c-strings
+ std::list<char *> lexedCStringList;
+ /**
+ This list is used to store elements of type char* generated during the lexing
+ process and not freed yet. In case of an error this list is freed.
+ */
+
+};
+
+#include "querytree.icc"
+
+#endif
+
diff --git a/qlparser/querytree.icc b/qlparser/querytree.icc
new file mode 100644
index 0000000..251704d
--- /dev/null
+++ b/qlparser/querytree.icc
@@ -0,0 +1,47 @@
+/*************************************************************
+ *
+ * Copyright (C) 1996 FORWISS
+ *
+ * INLINE SOURCE: querytree.icc
+ *
+ * MODULE: qlparser
+ * CLASS: QueryTree
+ *
+ * CHANGE HISTORY (append further entries):
+ * when who what
+ * ----------------------------------------------------------
+ * 04-09-96 Ritsch created
+ * 11-08-97 Ritsch merged with version 1.5.1.2
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+inline QtNode*
+QueryTree::getRoot() const
+{
+ return rootNode;
+};
+
+
+inline void
+QueryTree::setRoot( QtNode* root )
+{
+ rootNode = root;
+};
+
+
+inline void
+QueryTree::setOptimizationLevel( unsigned int level )
+{
+ optimizationLevel = level;
+};
+
+
+inline unsigned int
+QueryTree::getOptimizationLevel()
+{
+ return optimizationLevel;
+};
+
+
diff --git a/qlparser/rasml.awk b/qlparser/rasml.awk
new file mode 100644
index 0000000..124d6ab
--- /dev/null
+++ b/qlparser/rasml.awk
@@ -0,0 +1,9 @@
+BEGIN { paren = 0; sec = 0 }
+/\%\%/ { sec += 1; next; }
+sec!=1 { next; }
+# /^ *$/ { next; }
+/\/\// && !paren { x=$0; sub(/\/\/.*/, "", x); print x; next; }
+/{/ { x=$0; sub(/\{.*/, "", x); if(!paren) print x; paren += 1; }
+/(\/\*)/ { paren += 1; }
+/}|(\*\/)/ { paren -= 1; next; }
+!paren { print $0; }
diff --git a/qlparser/rasmlgrammar.html b/qlparser/rasmlgrammar.html
new file mode 100644
index 0000000..d192d21
--- /dev/null
+++ b/qlparser/rasmlgrammar.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+<HEAD>
+ <TITLE>RasDaMan: Specification</TITLE>
+ <META NAME="GENERATOR" CONTENT="Mozilla/3.0b6Gold (X11; I; HP-UX B.10.01 9000/770) [Netscape]">
+</HEAD>
+<BODY>
+
+<!-- BASE HREF=http://www.forwiss.tu-muenchen.de/ -->
+
+<H1><IMG SRC="/public/forwiss/projekte/rasdaman/rmanlogo-s.gif" ALT="[RasDaMan-Logo]" >Implementation
+Specification: RasML Grammar</H1>
+
+<P>The following grammar specifies RasML.</P>
+
+<PRE>
+
+<grammar>
+
+</PRE>
+
+<P><HR WIDTH="100%"></P>
+
+<P><A HREF="mailto:ritsch@forwiss.tu-muenchen.de">Roland Ritsch</A>, 1997-09-10</P>
+
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/qlparser/symtab.cc b/qlparser/symtab.cc
new file mode 100644
index 0000000..f96e49e
--- /dev/null
+++ b/qlparser/symtab.cc
@@ -0,0 +1,159 @@
+/*
+* 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:
+ * store symbols (identifiers) during the parse process
+ *
+ *
+ * COMMENTS:
+ * none
+ *
+ ***********************************************************************/
+
+//**************************************************************
+// Symbol Table class
+//**************************************************************
+
+//**************************************************************
+// Implementation
+//**************************************************************
+
+#include "symtab.hh"
+
+// constructor
+template <class T>
+SymbolTable<T>::SymbolTable() {
+ initScope();
+ STVars.clear();
+}
+
+// destructor
+template <class T>
+SymbolTable<T>::~SymbolTable() {
+ exitScope();
+}
+
+// put symbol in keys and in the hash-table
+template <class T>
+bool SymbolTable<T>::putSymbol(const std::string& symbol, T value) {
+ bool retVal = false;
+ // if not locally declared
+ if ( (STVars.find(symbol) == STVars.end()) ) {
+ if (getSymbol(symbol) == 0)
+ keys.push_back(symbol);
+ STVars[symbol] = value;
+ retVal = true;
+ } else
+ retVal = false;
+ return retVal;
+}
+
+// store symbol into hash-table
+template <class T>
+void SymbolTable<T>::storeSymbol( const std::string& symbol, T value ) {
+ STVars[symbol] = value;
+}
+
+// get symbol from table
+template <class T>
+T SymbolTable<T>::getSymbol( const std::string& symbol ) {
+ T retVal=NULL;
+
+ // find if locally declared
+ if ( !(STVars.find(symbol) == STVars.end()) )
+ {
+ retVal=STVars[symbol];
+ }
+ else
+ {
+ // find if declared in outer scopes
+ size_t idx=STScopes.size();
+ while (idx > 0) {
+ idx--;
+ if ( !(STScopes[idx].find(symbol) == STScopes[idx].end()) )
+ retVal=STScopes[idx][symbol];
+ }
+ }
+ return retVal;
+}
+
+// lookup symbol in table
+template <class T>
+bool SymbolTable<T>::lookupSymbol( const std::string& symbol ) {
+ bool retVal=false;
+
+ // find if locally declared
+ if ( !(STVars.find(symbol) == STVars.end()) )
+ {
+ retVal=true;
+ }
+ else
+ {
+ // find if declared in outer scopes
+ size_t idx = STScopes.size();
+ while (idx > 0) {
+ idx--;
+ if ( !(STScopes[idx].find(symbol) == STScopes[idx].end()) )
+ retVal=true;
+ }
+ }
+ return retVal;
+}
+
+// output the current scope
+template <class T>
+void SymbolTable<T>::outScope() {
+ RMInit::logOut << "Scope: " << STScopes.size() << endl;
+}
+
+// init scope by clearing inner symbols
+template <class T>
+void SymbolTable<T>::clearScope() {
+ STVars.clear();
+}
+
+// enter new scope
+template <class T>
+void SymbolTable<T>::initScope() {
+ STScopes.push_back(STVars);
+ STVars.clear();
+}
+
+// exit current scope to previous one
+template <class T>
+void SymbolTable<T>::exitScope() {
+ if (!STScopes.empty()) {
+ STVars = STScopes[STScopes.size() - 1];
+ STScopes.pop_back();
+ }
+}
+
+// wipe out everything from symbol table
+template <class T>
+void SymbolTable<T>::wipe() {
+ keys.clear();
+ STVars.clear();
+ STScopes.clear();
+}
diff --git a/qlparser/symtab.hh b/qlparser/symtab.hh
new file mode 100644
index 0000000..c3e5fba
--- /dev/null
+++ b/qlparser/symtab.hh
@@ -0,0 +1,110 @@
+#ifndef _SYMTAB_HH_
+#define _SYMTAB_HH_
+
+/*
+* 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:
+ * store symbols (identifiers) during the parse process
+ *
+ *
+ * COMMENTS:
+ * none
+ *
+ ***********************************************************************/
+
+#include <iostream>
+#include <vector>
+#include <map>
+#include <string>
+#include "raslib/rmdebug.hh"
+
+//@ManMemo: Module: {\bf qlparser}
+
+/*@Doc:
+
+ This class represents a generic symbol table. The operations on
+ symbols in the symbol table are: putSymbol, getSymbol, lookupSymbol.
+ The operations on scopes are: initScope, exitScope, outScope, clearScope,
+ wipe.
+
+*/
+
+template <class T>
+class SymbolTable {
+public:
+ /// This vector stores keys available in the map.
+ std::vector<std::string > keys;
+ /// This is an iterator for the vector storing the keys available in the map.
+ std::vector<std::string >::iterator keyIterator;
+
+ /// default constructor creates an empty symbol table, calls initScope(), clears local symbols.
+ SymbolTable();
+
+ /// default destructor, calls exitScope().
+ ~SymbolTable();
+
+ //@Man: Methods for symbol manipulation
+ //@{
+ /// Puts value at position symbol in the table. Returns true if it succeeded, otherwise false.
+ bool putSymbol( const std::string& symbol, T value );
+ /// Get value at position symbol from the table. If symbol doesn't exist, it returns NULL.
+ T getSymbol( const std::string& symbol );
+ /// Returns true if symbol is in table.
+ bool lookupSymbol( const std::string& symbol );
+ //@}
+
+ //@Man: Methods for scope manipulation
+ //@{
+ /// Enter new scope.
+ void initScope();
+ /// Exit current scope.
+ void exitScope();
+ /// Output current scope to RMInit::logOut.
+ void outScope();
+ /// Init scope by clearing inner symbols.
+ void clearScope();
+ /// Clear all symbols in all scopes.
+ void wipe();
+ //@}
+
+private:
+ /// Store symbol in map.
+ void storeSymbol( const std::string& symbol, T value ); // put only in the hash_map
+
+ /// Stores local variables.
+ std::map<std::string , T> STVars;
+
+ /// Stores scopes.
+ std::vector<std::map<std::string , T> > STScopes;
+};
+
+#ifdef EARLY_TEMPLATE
+#ifdef __EXECUTABLE__
+#include "symtab.cc"
+#endif
+#endif
+
+#endif
diff --git a/qlparser/test/Makefile b/qlparser/test/Makefile
new file mode 100644
index 0000000..fbf0bff
--- /dev/null
+++ b/qlparser/test/Makefile
@@ -0,0 +1,89 @@
+# -*-Makefile-*-
+#
+# 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>. # Top Level makefile. This points to the various modules that have to be build
+# and/or deployed
+#
+# MAKEFILE FOR:
+# test programs of module qlparser
+#
+# COMMENTS:
+#
+##################################################################
+#
+# This is just an example Makefile for a test program.
+# The dependency of the test program on the lib of the
+# corresponding module is in the Makefile of the module.
+#
+
+######################### Definitions ############################
+
+# all test programs
+SRCCXX = test_qlparser.cc test_evaluate.cc
+OBJS = ${SRCCXX:%.cc=%.o}
+ALLTESTS = ${SRCCXX:%.cc=%}
+MISCCLEAN := core
+
+# add compile and link options for STL
+CXXFLAGS += $(STLCXXFLAGS)
+LDFLAGS += $(STLLDFLAGS)
+
+########################### Targets ##############################
+
+# test target for qlparser
+.PHONY : qlparser
+qlparser: test_module test_qlparser
+
+.PHONY : evaluate
+evaluate: test_module test_evaluate
+
+.PHONY : test_module
+test_module:
+ cd $(RMANBASE)/qlparser; $(MAKE)
+
+test_evaluate: test_evaluate.o $(QLPARSER) \
+ $(RASLIB) \
+ $(CACHETAMGR) \
+ $(MDDIF) \
+ $(CATALOGIF) \
+ $(INDEXIF) \
+ $(INDEXMGR) \
+ $(BLOBIF) \
+ $(ADMINIF) \
+ $(CONVERSION)
+ $(PURIFY) $(CXX) $(LDFLAGS) $(BASEDBLDFLAGS) -o $@ $^
+
+
+test_qlparser: $(QLPARSER) test_qlparser.o $(RMANHOME)/qlparser/*.o \
+ $(QLPARSER) \
+ $(RMANHOME)/lib/librasodmg.a \
+ $(RASLIB) \
+ $(CACHETAMGR) \
+ $(MDDIF) \
+ $(CATALOGIF) \
+ $(INDEXIF) \
+ $(INDEXMGR) \
+ $(BLOBIF) \
+ $(ADMINIF) \
+ $(CONVERSION) \
+ $(RMANHOME)/rasdl/symbtbl.o
+ $(PURIFY) $(CXX) $(LDFLAGS) $(BASEDBLDFLAGS) -o $@ $^
+
diff --git a/qlparser/test/insertbin.cpp b/qlparser/test/insertbin.cpp
new file mode 100644
index 0000000..7779472
--- /dev/null
+++ b/qlparser/test/insertbin.cpp
@@ -0,0 +1,316 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ *
+ *
+ ************************************************************/
+
+#define FASTCONNECT
+#define DEBUG_MAIN
+#define DEBUG
+#define __EXECUTABLE__
+#include "debug.hh"
+#include "template_inst.hh"
+
+#define RMANVERSION 6100
+#define RASARCHITECTURE X86
+
+extern unsigned long maxTransferBufferSize = 4000000;
+bool udfEnabled = true;
+extern char* dbSchema = 0;
+extern int noTimeOut= 0;
+
+#include <iostream> // cout
+#include <vector>
+#include <stdio.h> // fopen, perror
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+
+#include "qlparser/querytree.hh"
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+
+
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "mddmgr/mddcoll.hh"
+#include "mddmgr/mddcolliter.hh"
+
+char globalConnectId[256]="RASBASE";
+
+// init globals for server initialization
+
+extern int yyparse(void *);
+extern char* myExecArgv0 = "";
+extern int globalOptimizationLevel = 4;
+extern char* beginParseString;
+extern char* iterParseString;
+
+extern int RManDebug;
+extern int RManInfo = 0;
+extern int rewrite = 0;
+extern int loadopt = 0;
+
+extern QueryTree* parseQueryTree;
+
+
+int checkArguments( int argc, char** argv, const char* searchText, int& optionValueIndex )
+{
+ int found = 0;
+ int i=1;
+
+ while( !found && i<argc )
+ found = !strcmp( searchText, argv[i++] );
+
+ if( found && i<argc && !strchr(argv[i],'-') )
+ optionValueIndex = i;
+ else
+ optionValueIndex = 0;
+
+ return found;
+}
+
+
+int main( int argc, char** argv )
+{
+ FILE* inFile;
+ char baseName[255];
+ char query[4096];
+ struct timezone tzp;
+ struct timeval startTime, stopTime, deltaTime;
+ int timeTest;
+ int optionValueIndex;
+ int noOutput;
+
+ if( checkArguments( argc, argv, "-h", optionValueIndex ) )
+ {
+ cout << "Usage: test_evaluate basename queryfile [options]" << endl;
+ cout << "Options: -h ... this help" << endl;
+ cout << " -l <file> ... log is printed to <file> (default: server.log)" << endl;
+ cout << " -l log is printed to standard out" << endl;
+ cout << " -d <file> ... debug output is printed to <file> (default: server.dbg)" << endl;
+ cout << " -d debug output is printed to standard out" << endl;
+ cout << " -dl n ... debug level is set to n (0-4, default: 0)" << endl;
+ cout << " - 0 = no / 4 = maximal debug information" << endl;
+ cout << " -opt n ... maximal optimization level (0-4, default: 4)" << endl;
+ cout << " - 0 = no / 4 = maximal optimization" << endl;
+ cout << " -t time test is enabled" << endl;
+ cout << " -nooutput ... no output of result" << endl;
+ cout << endl;
+ return 0;
+ }
+
+ strcpy( baseName, "RASBASE" );
+
+ inFile = fopen( "query", "r" );
+
+ if( inFile == NULL )
+ {
+ cout << "Error opening query file " << argv[2] << endl;
+ return -1;
+ }
+
+ fread( &query, 1, 4095, inFile );
+ fclose( inFile );
+
+ cout << endl << "Query:" << endl << endl << query << endl;
+
+ //
+ // open database, start transaction
+ //
+
+ // variables representing O2 database, ta and session
+ DatabaseIf db;
+ TransactionIf ta;
+
+ // don't forget to initialize before using AdminIf!
+ cout << "Connecting to O2 ..." << flush;
+ myExecArgv0 = argv[0];
+ AdminIf* myAdmin = AdminIf::instance();
+ cout << "OK" << endl;
+
+ // connect to the database
+ cout << "Opening database " << baseName << "... " << flush;
+ db.open( baseName );
+ cout << "OK" << endl;
+
+ cout << "Starting transaction ... " << flush;
+ ta.begin(&db);
+ cout << "OK" << endl;
+
+ //
+ // body of test program
+ //
+
+ beginParseString = query;
+ iterParseString = query;
+
+ parseQueryTree = new QueryTree(); // create a query tree object...
+
+ if( timeTest )
+ gettimeofday (&startTime, &tzp);
+
+ RMInit::logOut << "Parsing..." << flush;
+
+ if( yyparse(NULL) == 0 )
+ {
+ RMInit::logOut << "OK" << endl << endl;
+
+ parseQueryTree->printTree( 2, RMInit::logOut );
+ RMInit::logOut << endl;
+
+ parseQueryTree->getRoot()->printAlgebraicExpression();
+ cout << endl << endl;
+
+ unsigned int localOptimizationLevel = globalOptimizationLevel < parseQueryTree->getOptimizationLevel() ?
+ globalOptimizationLevel : parseQueryTree->getOptimizationLevel();
+
+ RMInit::logOut << "Optimizing query on level " << localOptimizationLevel << endl;
+ try
+ {
+ parseQueryTree->optimize( localOptimizationLevel );
+ }
+ catch( ParseInfo& info )
+ {
+ RMInit::logOut << endl << "Optimization Error" << endl;
+ info.printStatus();
+ cout << endl;
+
+ return 0;
+ }
+
+ RMInit::logOut << endl;
+ parseQueryTree->printTree( 2, RMInit::logOut );
+ RMInit::logOut << endl;
+ parseQueryTree->getRoot()->printAlgebraicExpression( RMInit::logOut );
+ RMInit::logOut << endl << endl;
+
+ RMInit::logOut << "Evaluating... " << flush;
+
+ vector<QtData*>* transColl = 0;
+
+ try
+ {
+ transColl = parseQueryTree->evaluateRetrieval();
+ }
+ catch( ParseInfo& info )
+ {
+ RMInit::logOut << endl << "Query Execution Error" << endl;
+ info.printStatus();
+ cout << endl;
+
+ return 0;
+ }
+
+ RMInit::logOut << "OK" << endl << endl;
+
+ if( timeTest )
+ {
+ gettimeofday(&stopTime, &tzp);
+
+ if(startTime.tv_usec > stopTime.tv_usec) {
+ stopTime.tv_usec += 1000000;
+ stopTime.tv_sec--;
+ }
+
+ deltaTime.tv_usec = stopTime.tv_usec - startTime.tv_usec;
+ deltaTime.tv_sec = stopTime.tv_sec - startTime.tv_sec;
+
+ cout << "Time for query processing " << deltaTime.tv_sec << " sec " << deltaTime.tv_usec << " msec " << endl;
+ }
+
+ vector<QtData*>::iterator transIter;
+ int collNum;
+ collNum = transColl->size();
+
+ cout << "The result collection has " << collNum << " entries." << endl;
+
+ if( transColl != 0 && !noOutput )
+ {
+ int i;
+
+ for( transIter = transColl->begin(), i=0; transIter != transColl->end(); transIter++, i++ )
+ {
+ QtData* mddObj = *transIter;
+
+ cout << endl << " --" << i << ". MDD object in set:" << endl << " ";
+ mddObj->printStatus();
+
+ /*vector<Tile* >* tiles = mddObj->getTiles();
+ vector<Tile* >::iterator tileIter;
+
+ for( tileIter = tiles->begin(); tileIter!=tiles->end(); tileIter++ )
+ {
+ cout << endl << " Tile" << endl;
+ (*tileIter)->printStatus();
+ }
+
+ // delete the Tile elements of the vector and the vector itself
+ // release( tiles->begin(), tiles->end() );
+ for( tileIter = tiles->begin(); tileIter!=tiles->end(); tileIter++ )
+ delete *tileIter;
+
+ delete tiles;*/
+ }
+
+ // release dynamic memory for the collection (delete MDDObjs)
+ // transColl->eraseAll();
+ delete transColl;
+
+ // delete transIter;
+ };
+
+ }
+ else {
+ RMInit::logOut << " failed" << endl;
+ printf("Error parsing query\n");
+ }
+
+ delete parseQueryTree;
+
+ //
+ // end of body
+ //
+
+ cout << "Committing transaction ... " << flush;
+ ta.commit();
+ cout << "OK" << endl;
+
+ cout << "Closing database ..." << flush;
+ db.close();
+ cout << "OK" << endl;
+ cout << "Ending O2 session ..." << endl;
+ delete myAdmin;
+ cout << "OK" << endl;
+
+ return 0;
+}
diff --git a/qlparser/test/template_inst.hh b/qlparser/test/template_inst.hh
new file mode 100644
index 0000000..9ce08ed
--- /dev/null
+++ b/qlparser/test/template_inst.hh
@@ -0,0 +1,152 @@
+/*
+* 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>.
+*/
+// This version was created based on rview. Let's see if the other programs compile
+// also.
+
+#ifndef _TEMPLATE_INST_RASLIB_
+#define _TEMPLATE_INST_RASLIB_
+
+#include <vector>
+
+#include "qlparser/symtab.hh"
+
+#include "raslib/attribute.hh"
+#include "raslib/itertype.hh"
+#include "raslib/dlist.hh"
+
+#include "tile.hh"
+
+#include "indexmgr/keyobject.hh"
+
+#include "reladminif/dbref.hh"
+#include "reladminif/dbobjectiditerator.hh"
+
+#include "relblobif/blobtile.hh"
+#include "relblobif/dbtile.hh"
+#include "relblobif/inlinetile.hh"
+
+#include "relcatalogif/typeiterator.hh"
+#include "relcatalogif/settype.hh"
+#include "relcatalogif/structtype.hh"
+#include "relcatalogif/mddtype.hh"
+#include "relcatalogif/inlineminterval.hh"
+#include "relcatalogif/dbminterval.hh"
+
+#include "relindexif/dbtcindex.hh"
+#include "relindexif/hierindex.hh"
+#include "relindexif/dbrcindexds.hh"
+
+#include "relmddif/dbmddobj.hh"
+#include "relmddif/dbmddset.hh"
+
+#include "relstorageif/dbudfds.hh"
+#include "relstorageif/dbudfpackageds.hh"
+#include "relstorageif/dbstoragelayout.hh"
+
+
+#include <qlparser/symtab.hh>
+#include <raslib/attribute.hh>
+#include <raslib/itertype.hh>
+#include <raslib/dlist.hh>
+#include <raslib/minterval.hh>
+
+
+#include "reladminif/dbref.hh"
+#include "reladminif/dbobjectiditerator.hh"
+
+#include "relindexif/dbtcindex.hh"
+#include "relindexif/hierindex.hh"
+#include "relindexif/dbrcindexds.hh"
+
+
+template class DBRef<DBHierIndex>;
+template class DBRef<DBRCIndexDS>;
+template class DBRef<DBTCIndex>;
+template class DBRef<BLOBTile>;
+template class DBRef<DBTile>;
+template class DBRef<InlineTile>;
+template class DBRef<DBMDDSet>;
+template class DBRef<DBMinterval>;
+template class DBRef<DBStorageLayout>;
+template class DBRef<DBUDFDS>;
+template class DBRef<DBUDFPackageDS>;
+template bool operator< (const DBRef<DBMDDObj>&, const DBRef<DBMDDObj>&);
+
+
+#include <rasodmg/tiling.hh>
+#include <rasodmg/stattiling.hh>
+#include <rasodmg/iterator.hh>
+#include <rasodmg/transaction.hh>
+#include <rasodmg/ref.hh>
+#include <rasodmg/object.hh>
+#include <rasodmg/set.hh>
+#include <rasodmg/collection.hh>
+#include <rasodmg/gmarray.hh>
+#include <rasodmg/marray.hh>
+#include <rasodmg/dirdecompose.hh>
+
+template class r_Ref<r_Object>;
+template class r_Ref<r_Minterval>;
+template class r_Collection<r_Transaction::GenRefElement *>;
+template class r_Set<r_Transaction::GenRefElement *>;
+template class r_Iterator<r_GMarray *>;
+template class r_Iterator<r_Ref<r_GMarray > >;
+template class r_Collection<r_Ref<r_GMarray> >;
+template class r_Collection<r_GMarray *>;
+template class r_Set<r_GMarray *>;
+template class r_Iterator<r_Ref<r_Object> >;
+template class r_IterType<r_Attribute>;
+template class r_Collection<r_Ref<r_Object> >;
+template class r_Set<r_Ref<r_Object> >;
+template class r_Iterator<r_Ref_Any>;
+template class r_Ref<r_GMarray>;
+template class r_Collection<r_Ref_Any>;
+template class std::vector<r_Minterval>;
+template class r_Iterator<r_Transaction::GenRefElement *>;
+template class r_Set<r_Ref<r_GMarray> >;
+template class r_Ref<r_Set<r_Ref<r_GMarray> > >;
+template class r_Set<r_Ref_Any>;
+template class r_Marray<r_ULong>;
+template class r_Marray<r_Char>;
+
+template class DBRef<DBMDDObj>;
+template class DBRef<DBObject>;
+
+template class DBObjectIdIterator<DBMDDObj>;
+template class DBObjectIterator<DBMDDObj>;
+template class DBObjectIterator<DBMDDSet>;
+template class DBObjectIterator<StructType>;
+template class DBObjectIterator<SetType>;
+template class DBObjectIterator<MDDType>;
+template class DBRef<StructType>;
+template class DBRef<SetType>;
+template class DBRef<MDDType>;
+
+
+template std::ostream& operator << (std::ostream& os, const std::vector<r_Minterval>& list);
+template std::ostream& operator << (std::ostream& os, const std::vector<r_Dir_Decompose>& list);
+template std::ostream& operator << (std::ostream& os, const std::vector<r_Access>& list);
+template std::ostream& operator << (std::ostream& os, const std::vector<double>& list);
+template class SymbolTable<int>;
+
+#endif
diff --git a/qlparser/test/test_evaluate.cc b/qlparser/test/test_evaluate.cc
new file mode 100644
index 0000000..b34ce9d
--- /dev/null
+++ b/qlparser/test/test_evaluate.cc
@@ -0,0 +1,338 @@
+/*
+* 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>.
+*/
+/*************************************************************
+ *
+ *
+ * COMMENTS:
+ *
+ *
+ *
+ ************************************************************/
+
+#include <iostream.h> // cout
+#include <stdio.h> // fopen, perror
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "qlparser/querytree.hh"
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "mddmgr/mddcoll.hh"
+#include "mddmgr/mddcolliter.hh"
+
+// init globals for server initialization
+RMINITGLOBALS('S')
+
+extern int yyparse();
+extern char* myExecArgv0 = "";
+extern int globalOptimizationLevel = 4;
+extern char* beginParseString;
+extern char* iterParseString;
+
+extern int RManDebug;
+extern int RManInfo = 0;
+extern int rewrite = 0;
+extern int loadopt = 0;
+
+extern QueryTree* parseQueryTree;
+
+
+int checkArguments( int argc, char** argv, const char* searchText, int& optionValueIndex )
+{
+ int found = 0;
+ int i=1;
+
+ while( !found && i<argc )
+ found = !strcmp( searchText, argv[i++] );
+
+ if( found && i<argc && !strchr(argv[i],'-') )
+ optionValueIndex = i;
+ else
+ optionValueIndex = 0;
+
+ return found;
+}
+
+
+int main( int argc, char** argv )
+{
+ FILE* inFile;
+ char baseName[255];
+ char query[4096];
+ struct timezone tzp;
+ struct timeval startTime, stopTime, deltaTime;
+ int timeTest;
+ int optionValueIndex;
+ int noOutput;
+
+ if( checkArguments( argc, argv, "-h", optionValueIndex ) )
+ {
+ cout << "Usage: test_evaluate basename queryfile [options]" << endl;
+ cout << "Options: -h ... this help" << endl;
+ cout << " -l <file> ... log is printed to <file> (default: server.log)" << endl;
+ cout << " -l log is printed to standard out" << endl;
+ cout << " -d <file> ... debug output is printed to <file> (default: server.dbg)" << endl;
+ cout << " -d debug output is printed to standard out" << endl;
+ cout << " -dl n ... debug level is set to n (0-4, default: 0)" << endl;
+ cout << " - 0 = no / 4 = maximal debug information" << endl;
+ cout << " -opt n ... maximal optimization level (0-4, default: 4)" << endl;
+ cout << " - 0 = no / 4 = maximal optimization" << endl;
+ cout << " -t time test is enabled" << endl;
+ cout << " -nooutput ... no output of result" << endl;
+ cout << endl;
+ return 0;
+ }
+
+ strcpy( baseName, argv[1] );
+
+ if( checkArguments( argc, argv, "-l", optionValueIndex ) )
+ if( optionValueIndex )
+ {
+ RMInit::logFileOut.open( argv[optionValueIndex] );
+ // RMInit::logOut = RMInit::logFileOut;
+ }
+ else {
+ // RMInit::logOut = cout.rdbuf();
+ }
+ else
+ {
+ // default
+ RMInit::logFileOut.open("server.log");
+ // RMInit::logOut = RMInit::logFileOut;
+ }
+
+ if( checkArguments( argc, argv, "-d", optionValueIndex ) )
+ if( optionValueIndex )
+ {
+ RMInit::dbgFileOut.open( argv[optionValueIndex] );
+ // RMInit::dbgOut = RMInit::dbgFileOut;
+ }
+ else {
+ // RMInit::logOut = cout.rdbuf();
+ }
+ else
+ {
+ // default
+ RMInit::dbgFileOut.open("server.dbg");
+ // RMInit::dbgOut = RMInit::dbgFileOut;
+ }
+
+ if( checkArguments( argc, argv, "-dl", optionValueIndex ) )
+ if( optionValueIndex )
+ RManDebug = (int)strtoul( argv[optionValueIndex], (char **)NULL, 10);
+
+ if( checkArguments( argc, argv, "-opt", optionValueIndex ) )
+ if( optionValueIndex )
+ globalOptimizationLevel = (int)strtoul( argv[optionValueIndex], (char **)NULL, 10);
+
+ timeTest = checkArguments( argc, argv, "-t", optionValueIndex );
+ noOutput = checkArguments( argc, argv, "-nooutput", optionValueIndex );
+
+ inFile = fopen( argv[2], "r" );
+
+ if( inFile == NULL )
+ {
+ cout << "Error opening query file " << argv[2] << endl;
+ return -1;
+ }
+
+ fread( &query, 1, 4095, inFile );
+ fclose( inFile );
+
+ cout << endl << "Query:" << endl << endl << query << endl;
+
+ //
+ // open database, start transaction
+ //
+
+ // variables representing O2 database, ta and session
+ DatabaseIf db;
+ TransactionIf ta;
+
+ // don't forget to initialize before using AdminIf!
+ cout << "Connecting to O2 ..." << flush;
+ myExecArgv0 = argv[0];
+ AdminIf* myAdmin = AdminIf::instance();
+ cout << "OK" << endl;
+
+ // connect to the database
+ cout << "Opening database " << baseName << "... " << flush;
+ db.open( baseName );
+ cout << "OK" << endl;
+
+ cout << "Starting transaction ... " << flush;
+ ta.begin(&db);
+ cout << "OK" << endl;
+
+ //
+ // body of test program
+ //
+
+ beginParseString = query;
+ iterParseString = query;
+
+ parseQueryTree = new QueryTree(); // create a query tree object...
+
+ if( timeTest )
+ gettimeofday (&startTime, &tzp);
+
+ RMInit::logOut << "Parsing..." << flush;
+
+ if( yyparse() == 0 )
+ {
+ RMInit::logOut << "OK" << endl << endl;
+
+ parseQueryTree->printTree( 2, RMInit::logOut );
+ RMInit::logOut << endl;
+
+ parseQueryTree->getRoot()->printAlgebraicExpression();
+ cout << endl << endl;
+
+ unsigned int localOptimizationLevel = globalOptimizationLevel < parseQueryTree->getOptimizationLevel() ?
+ globalOptimizationLevel : parseQueryTree->getOptimizationLevel();
+
+ RMInit::logOut << "Optimizing query on level " << localOptimizationLevel << endl;
+ try
+ {
+ parseQueryTree->optimize( localOptimizationLevel );
+ }
+ catch( ParseInfo& info )
+ {
+ RMInit::logOut << endl << "Optimization Error" << endl;
+ info.printStatus();
+ cout << endl;
+
+ return 0;
+ }
+
+ RMInit::logOut << endl;
+ parseQueryTree->printTree( 2, RMInit::logOut );
+ RMInit::logOut << endl;
+ parseQueryTree->getRoot()->printAlgebraicExpression( RMInit::logOut );
+ RMInit::logOut << endl << endl;
+
+ RMInit::logOut << "Evaluating... " << flush;
+
+ vector<QtData*>* transColl = 0;
+
+ try
+ {
+ transColl = parseQueryTree->evaluateRetrieval();
+ }
+ catch( ParseInfo& info )
+ {
+ RMInit::logOut << endl << "Query Execution Error" << endl;
+ info.printStatus();
+ cout << endl;
+
+ return 0;
+ }
+
+ RMInit::logOut << "OK" << endl << endl;
+
+ if( timeTest )
+ {
+ gettimeofday(&stopTime, &tzp);
+
+ if(startTime.tv_usec > stopTime.tv_usec) {
+ stopTime.tv_usec += 1000000;
+ stopTime.tv_sec--;
+ }
+
+ deltaTime.tv_usec = stopTime.tv_usec - startTime.tv_usec;
+ deltaTime.tv_sec = stopTime.tv_sec - startTime.tv_sec;
+
+ cout << "Time for query processing " << deltaTime.tv_sec << " sec " << deltaTime.tv_usec << " msec " << endl;
+ }
+
+ vector<QtData*>::iterator transIter;
+ int collNum;
+ collNum = transColl->size();
+
+ cout << "The result collection has " << collNum << " entries." << endl;
+
+ if( transColl != 0 && !noOutput )
+ {
+ int i;
+
+ for( transIter = transColl->begin(), i=0; transIter != transColl->end(); transIter++, i++ )
+ {
+ QtData* mddObj = *transIter;
+
+ cout << endl << " --" << i << ". MDD object in set:" << endl << " ";
+ mddObj->printStatus();
+
+ /*vector<Tile* >* tiles = mddObj->getTiles();
+ vector<Tile* >::iterator tileIter;
+
+ for( tileIter = tiles->begin(); tileIter!=tiles->end(); tileIter++ )
+ {
+ cout << endl << " Tile" << endl;
+ (*tileIter)->printStatus();
+ }
+
+ // delete the Tile elements of the vector and the vector itself
+ // release( tiles->begin(), tiles->end() );
+ for( tileIter = tiles->begin(); tileIter!=tiles->end(); tileIter++ )
+ delete *tileIter;
+
+ delete tiles;*/
+ }
+
+ // release dynamic memory for the collection (delete MDDObjs)
+ // transColl->eraseAll();
+ delete transColl;
+
+ // delete transIter;
+ };
+
+ }
+ else
+ RMInit::logOut << " failed" << endl;
+
+ delete parseQueryTree;
+
+ //
+ // end of body
+ //
+
+ cout << "Committing transaction ... " << flush;
+ ta.commit();
+ cout << "OK" << endl;
+
+ cout << "Closing database ..." << flush;
+ db.close();
+ cout << "OK" << endl;
+ cout << "Ending O2 session ..." << endl;
+ delete myAdmin;
+ cout << "OK" << endl;
+
+ return 0;
+}
diff --git a/qlparser/test/test_qlparser.cc b/qlparser/test/test_qlparser.cc
new file mode 100644
index 0000000..7753f2c
--- /dev/null
+++ b/qlparser/test/test_qlparser.cc
@@ -0,0 +1,205 @@
+/*
+* 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:
+ * Test program for the RasQL parser.
+ *
+ *
+ * COMMENTS:
+ *
+ *
+ ************************************************************/
+
+#ifdef EARLY_TEMPLATE
+#define __EXECUTABLE__
+#ifdef __GNUG__
+#include "qlparser/symtab.hh"
+#include "raslib/template_inst.hh"
+#endif
+#endif
+
+
+using namespace std;
+
+#define DEBUG_MAIN
+#include "debug-clt.hh"
+
+
+#include <iostream.h> // cout
+#include <stdio.h> // fopen, perror
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "qlparser/querytree.hh"
+
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+
+#include "mddmgr/mddobj.hh"
+#include "mddmgr/mddcoll.hh"
+#include "mddmgr/mddcolliter.hh"
+
+// init globals for server initialization
+// RMINITGLOBALS('C')
+
+extern int yyparse();
+extern char* myExecArgv0 = "";
+extern char* beginParseString;
+extern char* iterParseString;
+
+extern QueryTree* parseQueryTree;
+
+int main( int ac, char** av )
+{
+ FILE* inFile;
+ char baseName[255];
+ char query[4096];
+
+ //
+ // read program arguments
+ //
+
+ if( ac <= 2 )
+ {
+ cout << "usage: test_qlparser basename queryfile" << endl;
+ return -1;
+ }
+
+ strcpy( baseName, av[1] );
+
+ inFile = fopen( av[2], "r" );
+
+ if( inFile == NULL )
+ {
+ cout << "Error opening file " << av[1] << endl;
+ return -1;
+ }
+
+ fread( &query, 1, 4095, inFile );
+ fclose( inFile );
+
+ cout << "Query:" << endl << endl << query << endl;
+
+ //
+ // open database, start transaction
+ //
+
+ // variables representing O2 database, ta and session
+ DatabaseIf db;
+ TransactionIf ta;
+
+ // don't forget to initialize before using AdminIf!
+ cout << "Connecting to O2 ..." << flush;
+ myExecArgv0 = av[0];
+ AdminIf* myAdmin = AdminIf::instance();
+ cout << "OK" << endl;
+
+ // connect to the database
+ cout << "Opening database " << baseName << "... " << flush;
+ db.open( baseName );
+ cout << "OK" << endl;
+
+ cout << "Starting transaction ... " << flush;
+ ta.begin(&db);
+ cout << "OK" << endl;
+
+ //
+ // body of test program
+ //
+
+ beginParseString = query;
+ iterParseString = query;
+
+ parseQueryTree = new QueryTree(); // create a query tree object...
+
+ cout << endl << "Parsing ..." << flush;
+
+ if( !yyparse() )
+ cout << " worked" << endl;
+ else
+ cout << " failed" << endl;
+
+ cout << endl;
+ parseQueryTree->printTree(2);
+ cout << endl;
+ parseQueryTree->getRoot()->printAlgebraicExpression();
+ cout << endl;
+
+ cout << "Simplifying ..." << flush;
+ try
+ {
+ parseQueryTree->getRoot()->simplify();
+ }
+ catch( ParseInfo& info )
+ {
+ info.printStatus( RMInit::logOut );
+ cout << "FAILED" << endl;
+ }
+
+ cout << "OK" << endl;
+
+ cout << endl;
+ parseQueryTree->printTree(2);
+ cout << endl;
+ parseQueryTree->getRoot()->printAlgebraicExpression();
+ cout << endl;
+
+ delete parseQueryTree;
+
+ //
+ // end of body
+ //
+
+ cout << "Committing transaction ... " << flush;
+ ta.commit();
+ cout << "OK" << endl;
+
+ cout << "Closing database ..." << flush;
+ db.close();
+ cout << "OK" << endl;
+ cout << "Ending O2 session ..." << endl;
+ delete myAdmin;
+ cout << "OK" << endl;
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+