summaryrefslogtreecommitdiff
path: root/connectivity/source/parse
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/parse')
-rw-r--r--connectivity/source/parse/PColumn.cxx134
-rw-r--r--connectivity/source/parse/internalnode.cxx127
-rw-r--r--connectivity/source/parse/makefile.mk114
-rw-r--r--connectivity/source/parse/sqlbison.y4232
-rw-r--r--connectivity/source/parse/sqlflex.l592
-rw-r--r--connectivity/source/parse/sqliterator.cxx1583
-rw-r--r--connectivity/source/parse/sqlnode.cxx1399
7 files changed, 8181 insertions, 0 deletions
diff --git a/connectivity/source/parse/PColumn.cxx b/connectivity/source/parse/PColumn.cxx
new file mode 100644
index 000000000000..2644abc2c6f6
--- /dev/null
+++ b/connectivity/source/parse/PColumn.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * $RCSfile: PColumn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:14:28 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
+#include "connectivity/PColumn.hxx"
+#endif
+#ifndef _CONNECTIVITY_PROPERTYIDS_HXX_
+#include "propertyids.hxx"
+#endif
+
+using namespace connectivity;
+using namespace connectivity::parse;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+// -------------------------------------------------------------------------
+OParseColumn::OParseColumn(const Reference<XFastPropertySet>& _xColumn,sal_Bool _bCase)
+ : connectivity::sdbcx::OColumn( getString(_xColumn->getFastPropertyValue(PROPERTY_ID_NAME))
+ , getString(_xColumn->getFastPropertyValue(PROPERTY_ID_TYPENAME))
+ , getString(_xColumn->getFastPropertyValue(PROPERTY_ID_DEFAULTVALUE))
+ , getINT32(_xColumn->getFastPropertyValue(PROPERTY_ID_ISNULLABLE))
+ , getINT32(_xColumn->getFastPropertyValue(PROPERTY_ID_PRECISION))
+ , getINT32(_xColumn->getFastPropertyValue(PROPERTY_ID_SCALE))
+ , getINT32(_xColumn->getFastPropertyValue(PROPERTY_ID_TYPE))
+ , getBOOL(_xColumn->getFastPropertyValue(PROPERTY_ID_ISAUTOINCREMENT))
+ , sal_False
+ , getBOOL(_xColumn->getFastPropertyValue(PROPERTY_ID_ISCURRENCY))
+ , _bCase
+ )
+ , m_bFunction(sal_False)
+ , m_bDbasePrecisionChanged(sal_False)
+{
+ construct();
+}
+// -------------------------------------------------------------------------
+OParseColumn::OParseColumn( const ::rtl::OUString& _Name,
+ const ::rtl::OUString& _TypeName,
+ const ::rtl::OUString& _DefaultValue,
+ sal_Int32 _IsNullable,
+ sal_Int32 _Precision,
+ sal_Int32 _Scale,
+ sal_Int32 _Type,
+ sal_Bool _IsAutoIncrement,
+ sal_Bool _IsCurrency,
+ sal_Bool _bCase
+ ) : connectivity::sdbcx::OColumn(_Name,
+ _TypeName,
+ _DefaultValue,
+ _IsNullable,
+ _Precision,
+ _Scale,
+ _Type,
+ _IsAutoIncrement,
+ sal_False,
+ _IsCurrency,
+ _bCase)
+ , m_bFunction(sal_False)
+ , m_bDbasePrecisionChanged(sal_False)
+{
+ construct();
+}
+// -------------------------------------------------------------------------
+OParseColumn::~OParseColumn()
+{
+}
+// -------------------------------------------------------------------------
+void OParseColumn::construct()
+{
+ sal_Int32 nAttrib = isNew() ? 0 : PropertyAttribute::READONLY;
+
+ registerProperty(connectivity::PROPERTY_FUNCTION, PROPERTY_ID_FUNCTION, nAttrib,&m_bFunction, ::getCppuType(reinterpret_cast< sal_Bool*>(NULL)));
+ registerProperty(connectivity::PROPERTY_TABLENAME, PROPERTY_ID_TABLENAME, nAttrib,&m_aTableName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(connectivity::PROPERTY_REALNAME, PROPERTY_ID_REALNAME, nAttrib,&m_aRealName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(connectivity::PROPERTY_DBASEPRECISIONCHANGED, PROPERTY_ID_DBASEPRECISIONCHANGED, nAttrib,&m_bDbasePrecisionChanged, ::getCppuType(reinterpret_cast<sal_Bool*>(NULL)));
+
+}
+
diff --git a/connectivity/source/parse/internalnode.cxx b/connectivity/source/parse/internalnode.cxx
new file mode 100644
index 000000000000..57d5dbd6d7e6
--- /dev/null
+++ b/connectivity/source/parse/internalnode.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * $RCSfile: internalnode.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:14:28 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _CONNECTIVITY_SQLINTERNALNODE_HXX
+#include "internalnode.hxx"
+#endif
+
+#include <stl_algo.h>
+#ifndef _CONNECTIVITY_SQLPARSE_HXX
+#include <connectivity/sqlparse.hxx>
+#endif
+#ifndef _DEBUG_HXX //autogen
+#include <tools/debug.hxx>
+#endif
+
+using namespace connectivity;
+
+//-----------------------------------------------------------------------------
+OSQLInternalNode::OSQLInternalNode(const sal_Char* pNewValue,
+ SQLNodeType eNodeType,
+ sal_uInt32 nNodeID)
+ :OSQLParseNode(pNewValue,eNodeType,nNodeID)
+{
+ DBG_ASSERT(OSQLParser::s_pGarbageCollector, "Collector not initialized")
+ OSQLParser::s_pGarbageCollector->push_back(this);
+}
+
+//-----------------------------------------------------------------------------
+OSQLInternalNode::OSQLInternalNode(const ByteString &_NewValue,
+ SQLNodeType eNodeType,
+ sal_uInt32 nNodeID)
+ :OSQLParseNode(_NewValue,eNodeType,nNodeID)
+{
+ DBG_ASSERT(OSQLParser::s_pGarbageCollector, "Collector not initialized")
+ OSQLParser::s_pGarbageCollector->push_back(this);
+}
+
+//-----------------------------------------------------------------------------
+OSQLInternalNode::OSQLInternalNode(const sal_Unicode* pNewValue,
+ SQLNodeType eNodeType,
+ sal_uInt32 nNodeID)
+ :OSQLParseNode(pNewValue,eNodeType,nNodeID)
+{
+ DBG_ASSERT(OSQLParser::s_pGarbageCollector, "Collector not initialized")
+ OSQLParser::s_pGarbageCollector->push_back(this);
+}
+
+//-----------------------------------------------------------------------------
+OSQLInternalNode::OSQLInternalNode(const String &_NewValue,
+ SQLNodeType eNodeType,
+ sal_uInt32 nNodeID)
+ :OSQLParseNode(_NewValue,eNodeType,nNodeID)
+{
+ DBG_ASSERT(OSQLParser::s_pGarbageCollector, "Collector not initialized")
+ OSQLParser::s_pGarbageCollector->push_back(this);
+}
+
+
+//-----------------------------------------------------------------------------
+OSQLInternalNode::~OSQLInternalNode()
+{
+ // remove the node from the garbage list
+ DBG_ASSERT(OSQLParser::s_pGarbageCollector, "Collector not initialized")
+ if (!OSQLParser::s_pGarbageCollector->empty())
+ {
+ OSQLParser::s_pGarbageCollector->erase(
+ ::std::find(OSQLParser::s_pGarbageCollector->begin(), OSQLParser::s_pGarbageCollector->end(),
+ this));
+ }
+}
diff --git a/connectivity/source/parse/makefile.mk b/connectivity/source/parse/makefile.mk
new file mode 100644
index 000000000000..4d33aac1f973
--- /dev/null
+++ b/connectivity/source/parse/makefile.mk
@@ -0,0 +1,114 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:14:28 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=connectivity
+TARGET=sql
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/sqlbison.obj \
+ $(SLO)$/sqlflex.obj \
+ $(SLO)$/PColumn.obj \
+ $(SLO)$/sqliterator.obj \
+ $(SLO)$/sqlnode.obj \
+ $(SLO)$/fcode.obj \
+ $(SLO)$/fcomp.obj \
+ $(SLO)$/fanalyzer.obj \
+ $(SLO)$/internalnode.obj
+
+
+EXCEPTIONSFILES= \
+ $(SLO)$/sqlbison.obj \
+ $(SLO)$/PColumn.obj \
+ $(SLO)$/sqliterator.obj \
+ $(SLO)$/internalnode.obj \
+ $(SLO)$/fcode.obj \
+ $(SLO)$/fcomp.obj \
+ $(SLO)$/fanalyzer.obj \
+ $(SLO)$/sqlnode.obj
+
+all: \
+ $(MISC)$/sqlflex.cxx \
+ $(MISC)$/sqlbison.cxx \
+ ALLTAR
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
+$(MISC)$/sqlflex.cxx: sqlflex.l
+ +flex -i -8 -PSQLyy -L -o$(MISC)$/sqlflex.cxx sqlflex.l
+
+$(MISC)$/sqlbison.cxx: sqlbison.y
+ +bison -v -d -pSQLyy -l -bsql -o$(MISC)$/sqlbison.cxx sqlbison.y
+ -$(MKDIR) $(OUT)$/inc$/connectivity
+ +$(COPY) $(MISC)$/sqlbison.cxx.h $(OUT)$/inc$/connectivity$/sqlbison.hxx
+
diff --git a/connectivity/source/parse/sqlbison.y b/connectivity/source/parse/sqlbison.y
new file mode 100644
index 000000000000..f8aa3daf6254
--- /dev/null
+++ b/connectivity/source/parse/sqlbison.y
@@ -0,0 +1,4232 @@
+%{
+//--------------------------------------------------------------------------
+//
+// $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/connectivity/source/parse/sqlbison.y,v 1.1.1.1 2000-09-18 16:14:28 hr Exp $
+//
+// Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+//
+// First creation:
+// OJ
+//
+// Last change:
+// $Author: hr $ $Date: 2000-09-18 16:14:28 $ $Revision: 1.1.1.1 $
+//
+// Description:
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _VECTOR_
+#include <vector>
+#endif
+
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+
+#ifndef _CONNECTIVITY_SQLNODE_HXX
+#include <connectivity/sqlnode.hxx>
+#endif
+#ifndef _CONNECTIVITY_SQLPARSE_HXX
+#include <connectivity/sqlparse.hxx>
+#endif
+#ifndef _CONNECTIVITY_SQLINTERNALNODE_HXX
+#include <internalnode.hxx>
+#endif
+#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
+#include <com/sun/star/lang/Locale.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
+#include <com/sun/star/sdbc/DataType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATE_HPP_
+#include <com/sun/star/util/Date.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATSSUPPLIER_HPP_
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATS_HPP_
+#include <com/sun/star/util/XNumberFormats.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_NUMBERFORMAT_HPP_
+#include <com/sun/star/util/NumberFormat.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _TOOLS_SOLMATH_HXX //autogen wg. SolarMath
+#include <tools/solmath.hxx>
+#endif
+#ifndef _ISOLANG_HXX
+#include <tools/isolang.hxx>
+#endif
+#ifndef _DATETIME_HXX
+#include <tools/datetime.hxx>
+#endif
+#ifndef _TOOLS_INTN_HXX //autogen wg. International
+#include <tools/intn.hxx>
+#endif
+#ifndef _CONNECTIVITY_SQLSCAN_HXX
+#include "sqlscan.hxx"
+#endif
+#ifndef _OSL_DIAGNOSE_H_
+#include <osl/diagnose.h>
+#endif
+
+static String aEmptyString;
+
+static connectivity::OSQLInternalNode* newNode(const sal_Char* pNewValue,
+ const connectivity::SQLNodeType eNodeType,
+ const UINT16 nNodeID = 0)
+{
+
+ return new connectivity::OSQLInternalNode(pNewValue, eNodeType, nNodeID);
+}
+
+static connectivity::OSQLInternalNode* newNode(const ByteString& _NewValue,
+ const connectivity::SQLNodeType eNodeType,
+ const UINT16 nNodeID = 0)
+{
+
+ return new connectivity::OSQLInternalNode(_NewValue, eNodeType, nNodeID);
+}
+
+static connectivity::OSQLInternalNode* newNode(const String& _NewValue,
+ const connectivity::SQLNodeType eNodeType,
+ const UINT16 nNodeID = 0)
+{
+
+ return new connectivity::OSQLInternalNode(_NewValue, eNodeType, nNodeID);
+}
+
+
+// yyi ist die interne Nr. der Regel, die gerade reduziert wird.
+// Ueber die Mapping-Tabelle yyrmap wird daraus eine externe Regel-Nr.
+#define SQL_NEW_RULE newNode(aEmptyString, SQL_NODE_RULE, yyr1[yyn])
+#define SQL_NEW_LISTRULE newNode(aEmptyString, SQL_NODE_LISTRULE, yyr1[yyn])
+#define SQL_NEW_COMMALISTRULE newNode(aEmptyString, SQL_NODE_COMMALISTRULE, yyr1[yyn])
+
+
+connectivity::OSQLParser* xxx_pGLOBAL_SQLPARSER;
+
+#define YYERROR_VERBOSE
+
+#define SQLyyerror(s) \
+{ \
+ xxx_pGLOBAL_SQLPARSER->error(s); \
+}
+
+using namespace connectivity;
+#define SQLyylex xxx_pGLOBAL_SQLPARSER->SQLlex
+%}
+ /* symbolic tokens */
+
+%union {
+ connectivity::OSQLParseNode * pParseNode;
+}
+%type <pParseNode> '(' ')' ',' ':' ';' '?' '[' ']' '{' '}' '.'
+
+%token <pParseNode> SQL_TOKEN_STRING SQL_TOKEN_ACCESS_DATE SQL_TOKEN_INT SQL_TOKEN_REAL_NUM
+%token <pParseNode> SQL_TOKEN_INTNUM SQL_TOKEN_APPROXNUM SQL_TOKEN_NOT SQL_TOKEN_NAME
+
+ /* operators */
+%left <pParseNode> SQL_TOKEN_NAME
+%left <pParseNode> SQL_TOKEN_OR
+%left <pParseNode> SQL_TOKEN_AND
+
+%left <pParseNode> LESSEQ GREATEQ NOTEQUAL LESS GREAT EQUAL /* '<' '>' = <> < > <= >= != */
+%left <pParseNode> '+' '-'
+%left <pParseNode> '*' '/'
+%left <pParseNode> SQL_TOKEN_NATURAL SQL_TOKEN_CROSS SQL_TOKEN_FULL SQL_TOKEN_LEFT SQL_TOKEN_RIGHT
+%left <pParseNode> ')'
+%right <pParseNode> '='
+%right <pParseNode> '.'
+%right <pParseNode> '('
+
+
+%nonassoc <pParseNode> SQL_TOKEN_UMINUS
+
+
+
+ /* literal keyword tokens */
+
+%token <pParseNode> SQL_TOKEN_ALL SQL_TOKEN_ALTER SQL_TOKEN_AMMSC SQL_TOKEN_ANY SQL_TOKEN_AS SQL_TOKEN_ASC SQL_TOKEN_AT SQL_TOKEN_AUTHORIZATION SQL_TOKEN_AVG
+
+%token <pParseNode> SQL_TOKEN_BETWEEN SQL_TOKEN_BIT SQL_TOKEN_BIT_LENGTH SQL_TOKEN_BOTH SQL_TOKEN_BY
+
+%token <pParseNode> SQL_TOKEN_CAST SQL_TOKEN_CHARACTER SQL_TOKEN_CHAR_LENGTH SQL_TOKEN_CHECK SQL_TOKEN_COLLATE SQL_TOKEN_COMMIT SQL_TOKEN_CONTINUE SQL_TOKEN_CONVERT SQL_TOKEN_COUNT SQL_TOKEN_CREATE SQL_TOKEN_CROSS
+%token <pParseNode> SQL_TOKEN_CURRENT SQL_TOKEN_CURRENT_DATE SQL_TOKEN_CURRENT_TIME SQL_TOKEN_CURRENT_TIMESTAMP SQL_TOKEN_CURSOR
+
+%token <pParseNode> SQL_TOKEN_DATE SQL_TOKEN_DAY SQL_TOKEN_DEC SQL_TOKEN_DECIMAL SQL_TOKEN_DECLARE SQL_TOKEN_DEFAULT SQL_TOKEN_DELETE SQL_TOKEN_DESC
+%token <pParseNode> SQL_TOKEN_DISTINCT SQL_TOKEN_DOUBLE SQL_TOKEN_DROP
+
+%token <pParseNode> SQL_TOKEN_ESCAPE SQL_TOKEN_EXCEPT SQL_TOKEN_EXISTS SQL_TOKEN_EXTRACT SQL_TOKEN_FALSE SQL_TOKEN_FETCH SQL_TOKEN_FLOAT SQL_TOKEN_FOR SQL_TOKEN_FOREIGN SQL_TOKEN_FOUND SQL_TOKEN_FROM SQL_TOKEN_FULL
+
+%token <pParseNode> SQL_TOKEN_GRANT SQL_TOKEN_GROUP SQL_TOKEN_HAVING SQL_TOKEN_HOUR SQL_TOKEN_IN SQL_TOKEN_INDICATOR SQL_TOKEN_INNER SQL_TOKEN_INSERT SQL_TOKEN_INTEGER SQL_TOKEN_INTO SQL_TOKEN_IS SQL_TOKEN_INTERSECT
+
+%token <pParseNode> SQL_TOKEN_JOIN SQL_TOKEN_KEY SQL_TOKEN_LEADING SQL_TOKEN_LEFT SQL_TOKEN_LIKE SQL_TOKEN_LOCAL SQL_TOKEN_LOWER SQL_TOKEN_MINUTE SQL_TOKEN_MONTH
+%token <pParseNode> SQL_TOKEN_MAX SQL_TOKEN_MIN SQL_TOKEN_NATURAL SQL_TOKEN_NCHAR SQL_TOKEN_NULL SQL_TOKEN_NUMERIC
+
+%token <pParseNode> SQL_TOKEN_OCTECT_LENGTH SQL_TOKEN_OF SQL_TOKEN_ON SQL_TOKEN_OPTION SQL_TOKEN_ORDER SQL_TOKEN_OUTER
+
+%token <pParseNode> SQL_TOKEN_POSITION SQL_TOKEN_PRECISION SQL_TOKEN_PRIMARY SQL_TOKEN_PRIVILEGES SQL_TOKEN_PROCEDURE SQL_TOKEN_PUBLIC
+%token <pParseNode> SQL_TOKEN_REAL SQL_TOKEN_REFERENCES SQL_TOKEN_ROLLBACK SQL_TOKEN_RIGHT
+
+%token <pParseNode> SQL_TOKEN_SCHEMA SQL_TOKEN_SECOND SQL_TOKEN_SELECT SQL_TOKEN_SET SQL_TOKEN_SIZE SQL_TOKEN_SMALLINT SQL_TOKEN_SOME SQL_TOKEN_SQLCODE SQL_TOKEN_SQLERROR SQL_TOKEN_SUBSTRING SQL_TOKEN_SUM
+
+%token <pParseNode> SQL_TOKEN_TABLE SQL_TOKEN_TIME SQL_TOKEN_TIMESTAMP SQL_TOKEN_TIMEZONE_HOUR SQL_TOKEN_TIMEZONE_MINUTE SQL_TOKEN_TO SQL_TOKEN_TRAILING SQL_TOKEN_TRANSLATE SQL_TOKEN_TRIM SQL_TOKEN_TRUE SQL_TOKEN_UNION
+%token <pParseNode> SQL_TOKEN_UNIQUE SQL_TOKEN_UNKNOWN SQL_TOKEN_UPDATE SQL_TOKEN_UPPER SQL_TOKEN_USAGE SQL_TOKEN_USER SQL_TOKEN_USING SQL_TOKEN_VALUES SQL_TOKEN_VIEW
+%token <pParseNode> SQL_TOKEN_WHERE SQL_TOKEN_WITH SQL_TOKEN_WORK SQL_TOKEN_YEAR SQL_TOKEN_ZONE
+
+/* ODBC KEYWORDS */
+%token <pParseNode> SQL_TOKEN_CALL SQL_TOKEN_D SQL_TOKEN_FN SQL_TOKEN_T SQL_TOKEN_TS SQL_TOKEN_OJ
+
+
+%token <pParseNode> SQL_TOKEN_INVALIDSYMBOL
+
+/*%type <pParseNode> sql_single_statement */
+
+%type <pParseNode> sql /*schema */
+%type <pParseNode> column_def_opt_list column_def_opt table_constraint_def column_commalist
+%type <pParseNode> view_def opt_with_check_option opt_column_commalist privilege_def
+%type <pParseNode> opt_with_grant_option privileges operation_commalist operation
+%type <pParseNode> grantee_commalist grantee opt_order_by_clause ordering_spec_commalist
+%type <pParseNode> ordering_spec opt_asc_desc manipulative_statement commit_statement
+%type <pParseNode> /*delete_statement_positioned*/ delete_statement_searched fetch_statement
+%type <pParseNode> insert_statement values_or_query_spec
+%type <pParseNode> rollback_statement select_statement_into opt_all_distinct
+%type <pParseNode> /*update_statement_positioned*/ assignment_commalist assignment
+%type <pParseNode> update_statement_searched target_commalist target opt_where_clause
+%type <pParseNode> select_statement selection table_exp from_clause table_ref_commalist table_ref
+%type <pParseNode> where_clause opt_group_by_clause column_ref_commalist opt_having_clause
+%type <pParseNode> search_condition predicate comparison_predicate between_predicate
+%type <pParseNode> like_predicate opt_escape test_for_null in_predicate
+%type <pParseNode> all_or_any_predicate any_all_some existence_test subquery
+%type <pParseNode> scalar_exp_commalist parameter_ref literal
+%type <pParseNode> column_ref data_type column cursor parameter range_variable user /*like_check*/
+/* neue Regeln bei OJ */
+%type <pParseNode> derived_column as_clause table_name num_primary term num_value_exp
+%type <pParseNode> value_exp_primary num_value_fct unsigned_value_spec cast_spec set_fct_spec scalar_subquery
+%type <pParseNode> position_exp extract_exp length_exp general_value_spec
+%type <pParseNode> general_set_fct set_fct_type query_exp non_join_query_exp joined_table
+%type <pParseNode> non_join_query_term non_join_query_primary simple_table
+%type <pParseNode> table_value_const_list row_value_constructor row_value_const_list row_value_constructor_elem
+%type <pParseNode> qualified_join value_exp query_term join_type outer_join_type join_condition boolean_term
+%type <pParseNode> boolean_factor truth_value boolean_test boolean_primary named_columns_join join_spec
+%type <pParseNode> cast_operand cast_target factor datetime_value_exp /*interval_value_exp*/ datetime_term datetime_factor
+%type <pParseNode> datetime_primary datetime_value_fct time_zone time_zone_specifier /*interval_term*/ /*interval_qualifier*/
+%type <pParseNode> /*start_field*/ non_second_datetime_field /*end_field*/ /*single_datetime_field*/ extract_field datetime_field time_zone_field
+%type <pParseNode> extract_source char_length_exp octet_length_exp bit_length_exp select_sublist string_value_exp
+%type <pParseNode> char_value_exp concatenation char_factor char_primary string_value_fct char_substring_fct fold
+%type <pParseNode> form_conversion char_translation trim_fct trim_operands trim_spec bit_value_fct bit_substring_fct op_column_commalist
+%type <pParseNode> /*bit_concatenation*/ bit_value_exp bit_factor bit_primary collate_clause char_value_fct unique_spec value_exp_commalist in_predicate_value unique_test update_source
+%type <pParseNode> all query_primary as not for_length upper_lower comparison column_val cross_union /*opt_schema_element_list*/
+%type <pParseNode> /*op_authorization op_schema*/ nil_fkt schema_element base_table_def base_table_element base_table_element_commalist
+%type <pParseNode> column_def odbc_fct_spec odbc_call_spec odbc_fct_type op_parameter union_statement
+%type <pParseNode> op_odbc_call_parameter odbc_parameter_commalist odbc_parameter
+%%
+
+/* Parse Tree an OSQLParser zurueckliefern
+ * (der Zugriff ueber yyval nach Aufruf des Parsers scheitert,
+ *
+ */
+sql_single_statement:
+ sql
+ { xxx_pGLOBAL_SQLPARSER->setParseTree( $1 ); }
+ | sql ';'
+ { xxx_pGLOBAL_SQLPARSER->setParseTree( $1 ); }
+ ;
+/*
+sql_list:
+ sql_ ';'
+ {$$ = SQL_NEW_LISTRULE;
+ $$->append($1);
+ pSqlParseTreeRoot = $1; -- obsolete - Ergebnis in yyval! rdm }
+ | sql_list sql ';'
+ {$1->append($2);
+ $$ = $1;}
+ ;
+*/
+
+
+ /* schema definition language */
+ /* Note: other ``sql:'' rules appear later in the grammar */
+/***
+sql:
+ schema
+ ;
+
+op_authorization:
+ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_AUTHORIZATION user
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+op_schema:
+ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_NAME
+ | SQL_TOKEN_NAME '.' SQL_TOKEN_NAME
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ ;
+
+schema:
+ SQL_TOKEN_CREATE SQL_TOKEN_SCHEMA op_schema op_authorization opt_schema_element_list
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ }
+ ;
+
+opt_schema_element_list:
+ /* empty * / {$$ = SQL_NEW_RULE;}
+ | schema_glement_list
+ ;
+
+schema_element_list:
+ schema_element
+ {$$ = SQL_NEW_LISTRULE;
+ $$->append($1);}
+ | schema_element_list schema_element
+ {$1->append($2);
+ $$ = $1;}
+ ;
+*/
+sql:
+ schema_element
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+
+schema_element:
+ base_table_def
+ | view_def
+ | privilege_def
+ ;
+
+base_table_def:
+ SQL_TOKEN_CREATE SQL_TOKEN_TABLE table_name '(' base_table_element_commalist ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));}
+ ;
+
+base_table_element_commalist:
+ base_table_element
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | base_table_element_commalist ',' base_table_element
+ {$1->append($3);
+ $$ = $1;}
+ ;
+
+base_table_element:
+ column_def
+ | table_constraint_def
+ ;
+
+column_def:
+ column data_type column_def_opt_list
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ ;
+
+column_def_opt_list:
+ /* empty */ {$$ = SQL_NEW_LISTRULE;}
+ | column_def_opt_list column_def_opt
+ {$1->append($2);
+ $$ = $1;}
+ ;
+
+nil_fkt:
+ datetime_value_fct
+ ;
+unique_spec:
+ SQL_TOKEN_UNIQUE
+ | SQL_TOKEN_PRIMARY SQL_TOKEN_KEY
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+column_def_opt:
+ SQL_TOKEN_NOT SQL_TOKEN_NULL
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | unique_spec
+ | SQL_TOKEN_DEFAULT literal
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | SQL_TOKEN_DEFAULT SQL_TOKEN_NULL
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | SQL_TOKEN_DEFAULT SQL_TOKEN_USER
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | SQL_TOKEN_DEFAULT nil_fkt
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ | SQL_TOKEN_CHECK
+ | SQL_TOKEN_CHECK '(' search_condition ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_REFERENCES table_name
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | SQL_TOKEN_REFERENCES table_name '(' column_commalist ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($4);
+ $$->append($5 = newNode(")", SQL_NODE_PUNCTUATION));}
+ ;
+
+table_constraint_def:
+ unique_spec '(' column_commalist ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_FOREIGN SQL_TOKEN_KEY '(' column_commalist ')' SQL_TOKEN_REFERENCES table_name
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($4);
+ $$->append($5 = newNode(")", SQL_NODE_PUNCTUATION));
+ $$->append($6);
+ $$->append($7);}
+ | SQL_TOKEN_FOREIGN SQL_TOKEN_KEY '(' column_commalist ')' SQL_TOKEN_REFERENCES table_name '(' column_commalist ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($4);
+ $$->append($5 = newNode(")", SQL_NODE_PUNCTUATION));
+ $$->append($6);
+ $$->append($7);
+ $$->append($8 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($9);
+ $$->append($10 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_CHECK '(' search_condition ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));}
+ ;
+op_column_commalist:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | '(' column_commalist ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+column_commalist:
+ column_commalist ',' column
+ {$1->append($3);
+ $$ = $1;}
+ | column
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ ;
+
+view_def:
+ SQL_TOKEN_CREATE SQL_TOKEN_VIEW table_name opt_column_commalist SQL_TOKEN_AS select_statement opt_with_check_option
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ $$->append($7);}
+ ;
+
+opt_with_check_option:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_WITH SQL_TOKEN_CHECK SQL_TOKEN_OPTION
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);}
+ ;
+
+opt_column_commalist:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | '(' column_commalist ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));}
+ ;
+
+privilege_def:
+ SQL_TOKEN_GRANT privileges SQL_TOKEN_ON table_name SQL_TOKEN_TO grantee_commalist
+ opt_with_grant_option
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ $$->append($7);}
+ ;
+
+opt_with_grant_option:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_WITH SQL_TOKEN_GRANT SQL_TOKEN_OPTION
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);}
+ ;
+
+privileges:
+ SQL_TOKEN_ALL SQL_TOKEN_PRIVILEGES
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | operation_commalist
+ ;
+
+operation_commalist:
+ operation
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | operation_commalist ',' operation
+ {$1->append($3);
+ $$ = $1;}
+ ;
+
+operation:
+ SQL_TOKEN_SELECT
+ | SQL_TOKEN_INSERT opt_column_commalist
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | SQL_TOKEN_DELETE
+ | SQL_TOKEN_UPDATE opt_column_commalist
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | SQL_TOKEN_REFERENCES opt_column_commalist
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | SQL_TOKEN_USAGE
+ ;
+
+
+grantee_commalist:
+ grantee
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | grantee_commalist ',' grantee
+ {$1->append($3);
+ $$ = $1;}
+ ;
+
+grantee:
+ SQL_TOKEN_PUBLIC
+ | user
+ ;
+
+ /* module language */
+
+opt_order_by_clause:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_ORDER SQL_TOKEN_BY ordering_spec_commalist
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);}
+ ;
+
+ordering_spec_commalist:
+ ordering_spec
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | ordering_spec_commalist ',' ordering_spec
+ {$1->append($3);
+ $$ = $1;}
+ ;
+
+ordering_spec:
+/* SQL_TOKEN_INTNUM opt_asc_desc
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+*/
+ predicate opt_asc_desc
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+
+ | row_value_constructor_elem opt_asc_desc
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+
+opt_asc_desc:
+ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_ASC
+ | SQL_TOKEN_DESC
+ ;
+
+
+/***
+manipulative_statement_list:
+ manipulative_statement
+ {$$ = SQL_NEW_LISTRULE;
+ $$->append($1);}
+ | manipulative_statement_list manipulative_statement
+ {$1->append($2);
+ $$ = $1;}
+ ;
+***/
+
+sql:
+ {$$ = SQL_NEW_LISTRULE;}
+ ;
+not:
+ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_NOT
+ ;
+ /* manipulative statements */
+
+sql: manipulative_statement
+ ;
+
+manipulative_statement:
+ commit_statement
+/* | delete_statement_positioned*/
+ | delete_statement_searched
+ | fetch_statement
+ | insert_statement
+ | rollback_statement
+ | select_statement_into
+/* | update_statement_positioned*/
+ | update_statement_searched
+ | union_statement
+ | '{' odbc_call_spec '}'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("{", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode("}", SQL_NODE_PUNCTUATION));
+ }
+ ;
+
+union_statement:
+ select_statement
+ | union_statement SQL_TOKEN_UNION all select_statement
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ ;
+commit_statement:
+ SQL_TOKEN_COMMIT SQL_TOKEN_WORK
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+/*
+delete_statement_positioned:
+ SQL_TOKEN_DELETE SQL_TOKEN_FROM table_name SQL_TOKEN_WHERE SQL_TOKEN_CURRENT SQL_TOKEN_OF cursor
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ $$->append($7);}
+ ;
+*/
+delete_statement_searched:
+ SQL_TOKEN_DELETE SQL_TOKEN_FROM table_name opt_where_clause
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);}
+ ;
+
+fetch_statement:
+ SQL_TOKEN_FETCH cursor SQL_TOKEN_INTO target_commalist
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);}
+ ;
+
+insert_statement:
+ SQL_TOKEN_INSERT SQL_TOKEN_INTO table_name opt_column_commalist values_or_query_spec
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);}
+ ;
+values_or_query_spec:
+ SQL_TOKEN_VALUES table_value_const_list
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+
+table_value_const_list:
+ row_value_constructor
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | table_value_const_list ',' row_value_constructor
+ {$1->append($3);
+ $$ = $1;}
+ ;
+row_value_const_list:
+ row_value_constructor_elem
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | row_value_const_list ',' row_value_constructor_elem
+ {$1->append($3);
+ $$ = $1;}
+ ;
+row_value_constructor:
+ row_value_constructor_elem
+ | '(' row_value_const_list ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+/* | subquery
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }*/
+ ;
+row_value_constructor_elem:
+ value_exp /*[^')']*/
+ | SQL_TOKEN_NULL
+ | SQL_TOKEN_DEFAULT
+ ;
+
+
+rollback_statement:
+ SQL_TOKEN_ROLLBACK SQL_TOKEN_WORK
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+
+
+ /* INTO target_commalist herausgenommen */
+select_statement_into:
+ SQL_TOKEN_SELECT opt_all_distinct selection SQL_TOKEN_INTO target_commalist table_exp
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6); }
+ ;
+
+opt_all_distinct:
+ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_ALL
+ | SQL_TOKEN_DISTINCT
+
+ ;
+/*
+update_statement_positioned:
+ SQL_TOKEN_UPDATE table_name SQL_TOKEN_SET assignment_commalist
+ SQL_TOKEN_WHERE SQL_TOKEN_CURRENT SQL_TOKEN_OF cursor
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ $$->append($7);
+ $$->append($8);}
+ ;
+*/
+assignment_commalist:
+ assignment
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | assignment_commalist ',' assignment
+ {$1->append($3);
+ $$ = $1;}
+ ;
+
+assignment:
+ column EQUAL update_source
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);}
+ ;
+update_source:
+ value_exp
+ | SQL_TOKEN_NULL
+ | SQL_TOKEN_DEFAULT
+ ;
+update_statement_searched:
+ SQL_TOKEN_UPDATE table_name SQL_TOKEN_SET assignment_commalist opt_where_clause
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);}
+ ;
+
+target_commalist:
+ target
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | target_commalist ',' target
+ {$1->append($3);
+ $$ = $1;}
+ ;
+
+target:
+ parameter_ref
+ ;
+
+opt_where_clause:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | where_clause
+ ;
+
+ /* query expressions */
+
+query_term:
+ non_join_query_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+/* | joined_table
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+*/ ;
+/* SELECT STATEMENT */
+select_statement:
+ SQL_TOKEN_SELECT opt_all_distinct selection table_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ ;
+
+selection:
+ '*'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("*", SQL_NODE_PUNCTUATION));
+ }
+ | scalar_exp_commalist
+ ;
+
+table_exp:
+ from_clause
+ opt_where_clause
+ opt_group_by_clause
+ opt_having_clause
+ opt_order_by_clause
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);}
+ ;
+
+from_clause:
+ SQL_TOKEN_FROM table_ref_commalist
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+
+table_ref_commalist:
+ table_ref
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | table_ref_commalist ',' table_ref /*[^SQL_TOKEN_CROSS SQL_TOKEN_FULL SQL_TOKEN_UNION SQL_TOKEN_LEFT SQL_TOKEN_RIGHT SQL_TOKEN_INNER SQL_TOKEN_NATURAL]*/
+ {$1->append($3);
+ $$ = $1;}
+ ;
+as:
+ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_AS
+ {
+ $$ = SQL_NEW_RULE;
+ }
+ ;
+table_ref:
+ table_name
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | table_name as range_variable op_column_commalist
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ | '(' joined_table ')' as range_variable op_column_commalist
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ }
+ | joined_table
+ | '{' SQL_TOKEN_OJ joined_table '}'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("{", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3);
+ $$->append($4 = newNode("}", SQL_NODE_PUNCTUATION));
+ }
+ ;
+where_clause:
+ SQL_TOKEN_WHERE search_condition
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+
+opt_group_by_clause:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_GROUP SQL_TOKEN_BY column_ref_commalist
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);}
+ ;
+
+column_ref_commalist:
+ column_ref
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | column_ref_commalist ',' column_ref
+ {$1->append($3);
+ $$ = $1;}
+ ;
+
+opt_having_clause:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_HAVING search_condition
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+
+ /* search conditions */
+truth_value:
+ SQL_TOKEN_TRUE
+ | SQL_TOKEN_FALSE
+ | SQL_TOKEN_UNKNOWN
+ ;
+boolean_primary:
+ predicate
+ | '(' search_condition ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+subroutine:
+ {
+ if(!xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ YYERROR;
+ }
+ ;
+boolean_test:
+ boolean_primary
+ | boolean_primary SQL_TOKEN_IS truth_value
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ | boolean_primary SQL_TOKEN_IS SQL_TOKEN_NOT truth_value %prec SQL_TOKEN_IS
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ | subroutine SQL_TOKEN_NOT SQL_TOKEN_LIKE string_value_exp opt_escape
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($2);
+ $$->append($3);
+ if (xxx_pGLOBAL_SQLPARSER->buildLikeRule($$,$4,$5))
+ $$->append($5);
+ else
+ {
+ delete $$;
+ YYABORT;
+ }
+ }
+ else
+ YYERROR;
+ }
+ ;
+boolean_factor:
+ boolean_test
+ | SQL_TOKEN_NOT boolean_test
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+boolean_term:
+ boolean_factor
+ | boolean_term SQL_TOKEN_AND boolean_factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ | row_value_constructor_elem '\n' /*[^')' ',']*/
+ {
+ $$ = SQL_NEW_RULE;
+ INT16 nErg = xxx_pGLOBAL_SQLPARSER->buildComparsionRule($$,$1);
+ if(nErg == 1)
+ {
+ OSQLParseNode* pTemp = $$;
+ $$ = pTemp->removeAt((ULONG)0);
+ delete pTemp;
+ }
+ else
+ {
+ delete $$;
+ if(nErg)
+ YYERROR;
+ else
+ YYABORT;
+ }
+ }
+ | boolean_term SQL_TOKEN_AND literal
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ INT16 nErg = xxx_pGLOBAL_SQLPARSER->buildComparsionRule($$,$3);
+ if(nErg < 1)
+ {
+ delete $$;
+ if(nErg)
+ YYERROR;
+ else
+ YYABORT;
+ }
+
+ }
+ | boolean_term SQL_TOKEN_AND SQL_TOKEN_STRING
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ INT16 nErg = xxx_pGLOBAL_SQLPARSER->buildComparsionRule($$,$3);
+ if(nErg < 1)
+ {
+ delete $$;
+ if(nErg)
+ YYERROR;
+ else
+ YYABORT;
+ }
+
+ }
+ ;
+search_condition:
+ boolean_term
+ | search_condition SQL_TOKEN_OR boolean_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ ;
+predicate:
+ comparison_predicate
+ | between_predicate
+ | all_or_any_predicate
+ | existence_test
+ | unique_test
+ | test_for_null
+ | in_predicate
+ | like_predicate
+ ;
+
+comparison_predicate:
+ row_value_constructor comparison row_value_constructor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ | comparison row_value_constructor
+ {
+ $$ = SQL_NEW_RULE;
+ INT16 nErg = xxx_pGLOBAL_SQLPARSER->buildComparsionRule($$,$2,$1);
+ if(nErg == 1)
+ {
+ OSQLParseNode* pTemp = $$;
+ $$ = pTemp->removeAt((ULONG)0);
+ delete pTemp;
+ }
+ else
+ {
+ delete $$;
+ YYABORT;
+ }
+ }
+ ;
+comparison:
+ LESS
+ | NOTEQUAL
+ | EQUAL
+ | GREAT
+ | LESSEQ
+ | GREATEQ
+ ;
+between_predicate:
+ row_value_constructor SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ }
+ | row_value_constructor SQL_TOKEN_NOT SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ }
+ | subroutine SQL_TOKEN_NOT SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ }
+ else
+ YYERROR;
+ }
+ | subroutine SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ }
+ else
+ YYERROR;
+ }
+ ;
+
+like_predicate:
+ row_value_constructor SQL_TOKEN_NOT SQL_TOKEN_LIKE string_value_exp opt_escape
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ }
+ | row_value_constructor SQL_TOKEN_LIKE string_value_exp opt_escape
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ | row_value_constructor SQL_TOKEN_NOT SQL_TOKEN_LIKE value_exp_primary opt_escape
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ }
+ | row_value_constructor SQL_TOKEN_LIKE value_exp_primary opt_escape
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ /*| SQL_TOKEN_NOT
+ {
+ if(!xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ YYERROR;
+ } SQL_TOKEN_LIKE string_value_exp opt_escape
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($1);
+ $$->append($3);
+ if (xxx_pGLOBAL_SQLPARSER->buildLikeRule($$,$4,$5))
+ $$->append($5);
+ else
+ {
+ delete $$;
+ YYABORT;
+ }
+ }
+ else
+ YYERROR;
+ }
+ */| SQL_TOKEN_LIKE string_value_exp opt_escape
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($1);
+ if (xxx_pGLOBAL_SQLPARSER->buildLikeRule($$,$2,$3))
+ $$->append($3);
+ else
+ {
+ delete $$;
+ YYABORT;
+ }
+ }
+ else
+ YYERROR;
+ }
+ | SQL_TOKEN_LIKE value_exp_primary opt_escape
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($1);
+ if (xxx_pGLOBAL_SQLPARSER->buildLikeRule($$,$2,$3))
+ $$->append($3);
+ else
+ {
+ delete $$;
+ YYABORT;
+ }
+ }
+ else
+ YYERROR;
+ }
+ | subroutine SQL_TOKEN_NOT SQL_TOKEN_LIKE value_exp_primary opt_escape
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($2);
+ $$->append($3);
+ if (xxx_pGLOBAL_SQLPARSER->buildLikeRule($$,$4,$5))
+ $$->append($5);
+ else
+ {
+ delete $$;
+ YYABORT;
+ }
+ }
+ else
+ YYERROR;
+ }
+ ;
+
+opt_escape:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_ESCAPE string_value_exp
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ | '{' SQL_TOKEN_ESCAPE SQL_TOKEN_STRING '}'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("{", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3);
+ $$->append($4 = newNode("}", SQL_NODE_PUNCTUATION));
+ }
+ ;
+
+test_for_null:
+ row_value_constructor SQL_TOKEN_IS not SQL_TOKEN_NULL
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ | SQL_TOKEN_IS not SQL_TOKEN_NULL
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ else
+ YYERROR;
+ }
+ ;
+in_predicate_value:
+ subquery
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | '(' value_exp_commalist ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+in_predicate:
+ row_value_constructor not SQL_TOKEN_IN in_predicate_value
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ | subroutine SQL_TOKEN_IN in_predicate_value
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($2);
+ $$->append($3);
+ /*$$->append($3);*/
+ }
+ else
+ YYERROR;
+ }
+ ;
+all_or_any_predicate:
+ row_value_constructor comparison any_all_some subquery
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ | comparison any_all_some subquery
+ {
+ if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME));
+
+ $$ = SQL_NEW_RULE;
+ $$->append(pColumnRef);
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ else
+ YYERROR;
+ }
+ ;
+
+any_all_some:
+ SQL_TOKEN_ANY
+ | SQL_TOKEN_ALL
+ | SQL_TOKEN_SOME
+ ;
+
+existence_test:
+ SQL_TOKEN_EXISTS subquery
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+unique_test:
+ SQL_TOKEN_UNIQUE subquery
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+subquery:
+ '(' query_exp ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));}
+ ;
+
+ /* scalar expressions */
+scalar_exp_commalist:
+ select_sublist
+ {
+ $$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);
+ }
+ | scalar_exp_commalist ',' select_sublist
+ {
+ $1->append($3);
+ $$ = $1;
+ }
+ ;
+select_sublist:
+ table_name '.' '*'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($3 = newNode("*", SQL_NODE_PUNCTUATION));
+ }
+ | derived_column
+
+ ;
+
+parameter_ref:
+ parameter
+ ;
+
+/*
+op_like:
+ '*'
+ {
+ $$ = newNode("*", SQL_NODE_PUNCTUATION);
+ }
+ | '?'
+ {
+ $$ = newNode("?", SQL_NODE_PUNCTUATION);
+ }
+ | op_like '*'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("*", SQL_NODE_PUNCTUATION));
+ xxx_pGLOBAL_SQLPARSER->reduceLiteral($$, FALSE);
+ }
+ | op_like '?'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("?", SQL_NODE_PUNCTUATION));
+ xxx_pGLOBAL_SQLPARSER->reduceLiteral($$, FALSE);
+ }
+ ;
+*/
+
+literal:
+/* SQL_TOKEN_STRING
+ | */SQL_TOKEN_INT
+ | SQL_TOKEN_REAL_NUM
+ | SQL_TOKEN_INTNUM
+ | SQL_TOKEN_APPROXNUM
+ | SQL_TOKEN_ACCESS_DATE
+/* rules for predicate check */
+ | literal SQL_TOKEN_STRING
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ xxx_pGLOBAL_SQLPARSER->reduceLiteral($$, TRUE);
+ }
+ else
+ YYERROR;
+ }
+ | literal SQL_TOKEN_INT
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ xxx_pGLOBAL_SQLPARSER->reduceLiteral($$, TRUE);
+ }
+ else
+ YYERROR;
+ }
+ | literal SQL_TOKEN_REAL_NUM
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ xxx_pGLOBAL_SQLPARSER->reduceLiteral($$, TRUE);
+ }
+ else
+ YYERROR;
+ }
+ | literal SQL_TOKEN_APPROXNUM
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ xxx_pGLOBAL_SQLPARSER->reduceLiteral($$, TRUE);
+ }
+ else
+ YYERROR;
+ }
+ ;
+
+ /* miscellaneous */
+as_clause:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_AS column
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ | column
+ ;
+position_exp:
+ SQL_TOKEN_POSITION '(' string_value_exp SQL_TOKEN_IN string_value_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+num_value_fct:
+ position_exp
+ | extract_exp
+ | length_exp
+ ;
+char_length_exp:
+ SQL_TOKEN_CHAR_LENGTH '(' string_value_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+octet_length_exp:
+ SQL_TOKEN_OCTECT_LENGTH '(' string_value_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+bit_length_exp:
+ SQL_TOKEN_BIT_LENGTH '(' string_value_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+length_exp:
+ char_length_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | octet_length_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | bit_length_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+datetime_field:
+ non_second_datetime_field
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_SECOND
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+extract_field:
+ datetime_field
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | time_zone_field
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+time_zone_field:
+ SQL_TOKEN_TIMEZONE_HOUR
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_TIMEZONE_MINUTE
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+extract_source:
+ datetime_value_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+/* | interval_value_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ } */
+ ;
+extract_exp:
+ SQL_TOKEN_EXTRACT '(' extract_field SQL_TOKEN_FROM extract_source ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+unsigned_value_spec:
+ literal
+ | general_value_spec
+ ;
+general_value_spec:
+ parameter
+ | SQL_TOKEN_USER
+ ;
+set_fct_spec:
+ general_set_fct
+ | '{' odbc_fct_spec '}'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("{", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode("}", SQL_NODE_PUNCTUATION));
+ }
+ | SQL_TOKEN_NAME '(' value_exp_commalist ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+op_parameter:
+ {$$ = SQL_NEW_RULE;}
+ | '?' EQUAL
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("?", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ }
+ ;
+odbc_call_spec:
+ op_parameter SQL_TOKEN_CALL table_name op_odbc_call_parameter
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ ;
+
+op_odbc_call_parameter:
+ {$$ = SQL_NEW_RULE;}
+ | '(' odbc_parameter_commalist ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+
+odbc_parameter_commalist:
+ odbc_parameter
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | odbc_parameter_commalist ',' odbc_parameter
+ {
+ $1->append($3);
+ $$ = $1;
+ }
+ ;
+odbc_parameter:
+ /* empty */ {$$ = SQL_NEW_RULE;}
+ | literal
+ | parameter
+ ;
+
+odbc_fct_spec:
+ odbc_fct_type SQL_TOKEN_STRING
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+
+odbc_fct_type:
+ SQL_TOKEN_FN
+ | SQL_TOKEN_D
+ | SQL_TOKEN_T
+ | SQL_TOKEN_TS
+ ;
+
+general_set_fct:
+ set_fct_type '(' opt_all_distinct value_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ | SQL_TOKEN_COUNT '(' '*' ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3 = newNode("*", SQL_NODE_PUNCTUATION));
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ | SQL_TOKEN_COUNT '(' opt_all_distinct value_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+set_fct_type:
+ SQL_TOKEN_AVG
+ | SQL_TOKEN_MAX
+ | SQL_TOKEN_MIN
+ | SQL_TOKEN_SUM
+ ;
+
+outer_join_type:
+ SQL_TOKEN_LEFT %prec SQL_TOKEN_LEFT
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_RIGHT %prec SQL_TOKEN_RIGHT
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_FULL %prec SQL_TOKEN_FULL
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+join_condition:
+ SQL_TOKEN_ON search_condition
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+join_spec:
+ join_condition
+ | named_columns_join
+ ;
+join_type:
+ SQL_TOKEN_INNER
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | outer_join_type
+ | outer_join_type SQL_TOKEN_OUTER
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+cross_union:
+ table_ref /*[SQL_TOKEN_CROSS]*/ SQL_TOKEN_CROSS SQL_TOKEN_JOIN table_ref %prec SQL_TOKEN_CROSS
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ ;
+
+qualified_join:
+ /* wenn SQL_TOKEN_NATURAL, dann keine join_spec */
+ table_ref /*[SQL_TOKEN_NATURAL]*/ SQL_TOKEN_NATURAL join_type SQL_TOKEN_JOIN table_ref %prec SQL_TOKEN_NATURAL
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ }
+ | table_ref join_type SQL_TOKEN_JOIN table_ref join_spec
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ }
+ | cross_union
+ ;
+joined_table:
+ qualified_join
+/* | query_exp*/
+ | '(' joined_table ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+
+ ;
+named_columns_join:
+ SQL_TOKEN_USING '(' column_commalist ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+simple_table:
+ select_statement
+ | values_or_query_spec
+ ;
+
+non_join_query_primary:
+ simple_table
+ | '(' non_join_query_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+non_join_query_term:
+ non_join_query_primary
+ | query_term SQL_TOKEN_INTERSECT all query_primary
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ ;
+query_primary:
+ non_join_query_primary
+ /*| joined_table*/
+ ;
+non_join_query_exp:
+ non_join_query_term
+ | query_exp SQL_TOKEN_UNION all query_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ | query_exp SQL_TOKEN_EXCEPT all query_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ ;
+all:
+ /* empty*/ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_ALL
+ ;
+query_exp:
+ non_join_query_exp /*[^')']*/
+ ;
+scalar_subquery:
+ subquery
+ ;
+cast_operand:
+ value_exp
+ | SQL_TOKEN_NULL
+ ;
+cast_target:
+ table_name
+ | data_type
+ ;
+cast_spec:
+ SQL_TOKEN_CAST '(' cast_operand SQL_TOKEN_AS cast_target ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+value_exp_primary:
+ unsigned_value_spec
+ | column_ref
+ | set_fct_spec
+ | scalar_subquery
+ | '(' value_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ | cast_spec
+ ;
+
+num_primary:
+ value_exp_primary
+ | num_value_fct
+ ;
+factor:
+ num_primary
+ | '-' num_primary %prec SQL_TOKEN_UMINUS
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("-", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ }
+ | '+' num_primary %prec SQL_TOKEN_UMINUS
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("+", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ }
+ ;
+
+term:
+ factor
+ | term '*' factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("*", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ | term '/' factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("/", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ ;
+
+num_value_exp:
+ term
+ | num_value_exp '+' term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("+", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ | num_value_exp '-' term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("-", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ ;
+datetime_primary:
+/* value_exp_primary
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ |*/ datetime_value_fct
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+datetime_value_fct:
+ SQL_TOKEN_CURRENT_DATE
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_CURRENT_TIME
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_CURRENT_TIMESTAMP
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+time_zone:
+ SQL_TOKEN_AT time_zone_specifier
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+time_zone_specifier:
+ SQL_TOKEN_LOCAL
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+/* | SQL_TOKEN_TIME SQL_TOKEN_ZONE interval_value_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }*/
+ ;
+datetime_factor:
+ datetime_primary
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | datetime_primary time_zone
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+datetime_term:
+ datetime_factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+/*
+interval_term:
+ literal
+ | interval_term '*' factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("*", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ | interval_term '/' factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("/", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ ;
+*/
+datetime_value_exp:
+ datetime_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+/* | interval_value_exp '+' datetime_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("+", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ | datetime_value_exp '+' interval_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("+", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ | datetime_value_exp '-' interval_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("-", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+*/ ;
+/*
+interval_value_exp:
+ interval_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | interval_value_exp '+' interval_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("+", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ | interval_value_exp '-' interval_term
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("-", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ | '(' datetime_value_exp '-' datetime_term ')' interval_qualifier
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode("-", SQL_NODE_PUNCTUATION));
+ $$->append($4);
+ $$->append($5 = newNode(")", SQL_NODE_PUNCTUATION));
+ $$->append($6);
+ }
+ ;
+*/
+non_second_datetime_field:
+ SQL_TOKEN_YEAR
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_MONTH
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_DAY
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_HOUR
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_MINUTE
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+/*start_field:
+ non_second_datetime_field
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | non_second_datetime_field '(' SQL_TOKEN_INTNUM ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+end_field:
+ non_second_datetime_field
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_SECOND
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_SECOND '(' SQL_TOKEN_INTNUM ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+*/
+/*
+single_datetime_field:
+ non_second_datetime_field
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | non_second_datetime_field '(' SQL_TOKEN_INTNUM ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ | SQL_TOKEN_SECOND
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | SQL_TOKEN_SECOND '(' SQL_TOKEN_INTNUM ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ | SQL_TOKEN_SECOND '(' SQL_TOKEN_INTNUM ',' SQL_TOKEN_INTNUM ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(",", SQL_NODE_PUNCTUATION));
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+*/
+/*
+interval_qualifier:
+ start_field SQL_TOKEN_TO end_field
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ | single_datetime_field
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+*/
+value_exp_commalist:
+ value_exp
+ {$$ = SQL_NEW_COMMALISTRULE;
+ $$->append($1);}
+ | value_exp_commalist ',' value_exp
+ {$1->append($3);
+ $$ = $1;}
+ /* this rule is only valid if we check predicates */
+ | value_exp_commalist ';' value_exp
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ $1->append($3);
+ $$ = $1;
+ }
+ else
+ YYERROR;
+ }
+ ;
+value_exp:
+ num_value_exp /*[^')']*/
+ | string_value_exp
+ | datetime_value_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+string_value_exp:
+ char_value_exp
+/* | bit_value_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+*/ ;
+char_value_exp:
+ char_factor
+ | concatenation
+ ;
+concatenation:
+ char_value_exp '+' char_factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("+", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ ;
+
+char_primary:
+ SQL_TOKEN_STRING
+ | string_value_fct
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+collate_clause:
+ SQL_TOKEN_COLLATE table_name
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+char_factor:
+ char_primary
+ | char_primary collate_clause
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+string_value_fct:
+ char_value_fct
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | bit_value_fct
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+bit_value_fct:
+ bit_substring_fct
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+bit_substring_fct:
+ SQL_TOKEN_SUBSTRING '(' bit_value_exp SQL_TOKEN_FROM string_value_exp for_length ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ $$->append($7 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+bit_value_exp:
+ bit_factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+/*
+ bit_concatenation
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ |
+bit_concatenation:
+ bit_value_exp '+' bit_factor
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("+", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ }
+ ;
+*/
+bit_factor:
+ bit_primary
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+bit_primary:
+ {$$ = SQL_NEW_RULE;}
+/* value_exp_primary
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | string_value_fct
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }*/
+ ;
+char_value_fct:
+ char_substring_fct
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | fold
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | form_conversion
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | char_translation
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ | trim_fct
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ }
+ ;
+for_length:
+ {$$ = SQL_NEW_RULE;}
+ | SQL_TOKEN_FOR string_value_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+char_substring_fct:
+ SQL_TOKEN_SUBSTRING '(' string_value_exp SQL_TOKEN_FROM string_value_exp for_length ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6);
+ $$->append($7 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+upper_lower:
+ SQL_TOKEN_UPPER
+ | SQL_TOKEN_LOWER
+ ;
+fold:
+ upper_lower '(' string_value_exp ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+form_conversion:
+ SQL_TOKEN_CONVERT '(' string_value_exp SQL_TOKEN_USING table_name ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+char_translation:
+ SQL_TOKEN_TRANSLATE '(' string_value_exp SQL_TOKEN_USING table_name ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4);
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+trim_fct:
+ SQL_TOKEN_TRIM '(' trim_operands ')'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));
+ }
+ ;
+trim_operands:
+ string_value_exp
+ | trim_spec string_value_exp SQL_TOKEN_FROM string_value_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ $$->append($4);
+ }
+ | trim_spec SQL_TOKEN_FROM string_value_exp
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ $$->append($3);
+ }
+ ;
+trim_spec:
+ SQL_TOKEN_BOTH
+ | SQL_TOKEN_LEADING
+ | SQL_TOKEN_TRAILING
+ ;
+
+derived_column:
+ value_exp as_clause
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);
+ }
+ ;
+/* Tabellenname */
+table_name:
+ SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);}
+ | SQL_TOKEN_NAME '.' SQL_TOKEN_NAME %prec SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($3);}
+ | SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME %prec SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2= newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($5);}
+ | SQL_TOKEN_NAME ':' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2= newNode(":", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($5);}
+/* | SQL_TOKEN_NAME ';' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2= newNode(";", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($5);}
+*/ ;
+column_ref:
+ column
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);}
+ | SQL_TOKEN_NAME '.' column_val %prec '.'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($3);}
+ | SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' column_val %prec '.'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($5);}
+ | SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' column_val %prec '.'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2= newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($5);
+ $$->append($6 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($7);
+ }
+ | SQL_TOKEN_NAME ':' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' column_val %prec '.'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2= newNode(":", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($5);
+ $$->append($6 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($7);
+ }
+/* | SQL_TOKEN_NAME ';' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' column_val
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2= newNode(";", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($5);
+ $$->append($6 = newNode(".", SQL_NODE_PUNCTUATION));
+ $$->append($7);
+ }
+*/ ;
+
+ /* data types */
+column_val:
+ column
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);}
+ | '*'
+ {
+ $$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("*", SQL_NODE_PUNCTUATION));
+ }
+ ;
+data_type:
+ SQL_TOKEN_CHARACTER
+ | SQL_TOKEN_CHARACTER '(' SQL_TOKEN_INTNUM ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_NUMERIC
+ | SQL_TOKEN_NUMERIC '(' SQL_TOKEN_INTNUM ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_NUMERIC '(' SQL_TOKEN_INTNUM ',' SQL_TOKEN_INTNUM ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(",", SQL_NODE_PUNCTUATION));
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_DECIMAL
+ | SQL_TOKEN_DECIMAL '(' SQL_TOKEN_INTNUM ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_DECIMAL '(' SQL_TOKEN_INTNUM ',' SQL_TOKEN_INTNUM ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(",", SQL_NODE_PUNCTUATION));
+ $$->append($5);
+ $$->append($6 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_INTEGER
+ | SQL_TOKEN_SMALLINT
+ | SQL_TOKEN_FLOAT
+ | SQL_TOKEN_FLOAT '(' SQL_TOKEN_INTNUM ')'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION));
+ $$->append($3);
+ $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION));}
+ | SQL_TOKEN_REAL
+ | SQL_TOKEN_DOUBLE SQL_TOKEN_PRECISION
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);
+ $$->append($2);}
+ ;
+
+ /* the various things you can name */
+
+column:
+ SQL_TOKEN_NAME
+ | SQL_TOKEN_POSITION
+ {
+ UINT16 nNod = $$->getRuleID();
+ delete $$;
+ $$ = newNode(xxx_pGLOBAL_SQLPARSER->TokenIDToStr(nNod), SQL_NODE_NAME);
+ }
+ | SQL_TOKEN_CHAR_LENGTH
+ {
+ UINT16 nNod = $$->getRuleID();
+ delete $$;
+ $$ = newNode(xxx_pGLOBAL_SQLPARSER->TokenIDToStr(nNod), SQL_NODE_NAME);
+ }
+ | SQL_TOKEN_EXTRACT
+ {
+ UINT16 nNod = $$->getRuleID();
+ delete $$;
+ $$ = newNode(xxx_pGLOBAL_SQLPARSER->TokenIDToStr(nNod), SQL_NODE_NAME);
+ }
+ ;
+
+cursor: SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);}
+ ;
+
+/***
+module: SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);}
+ ;
+***/
+
+parameter:
+ ':' SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1 = newNode(":", SQL_NODE_PUNCTUATION));
+ $$->append($2);}
+ | '?'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("?", SQL_NODE_PUNCTUATION));}
+ | '[' SQL_TOKEN_NAME ']'
+ {$$ = SQL_NEW_RULE;
+ $$->append($1 = newNode("[", SQL_NODE_PUNCTUATION));
+ $$->append($2);
+ $$->append($3 = newNode("]", SQL_NODE_PUNCTUATION));}
+ ;
+
+/***
+procedure: SQL_TOKEN_NAME
+ {$$ = SQL_NEW_RULE;
+ $$->append($1);}
+ ;
+***/
+
+range_variable: SQL_TOKEN_NAME
+ ;
+
+user: SQL_TOKEN_NAME
+ ;
+
+/* PREDICATECHECK RULES */
+sql:
+ search_condition /* checking predicats */
+ {
+ if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())
+ {
+ $$ = $1;
+ }
+ else
+ YYERROR;
+ }
+%%
+
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::osl;
+// using namespace connectivity;
+
+//============================================================
+//= a helper for static ascii pseudo-unicode strings
+//============================================================
+// string constants
+struct _ConstAsciiString_
+{
+ sal_Int32 length;
+ sal_Char const* str;
+
+ operator rtl::OUString () const { return rtl::OUString(str, length, RTL_TEXTENCODING_ASCII_US); }
+// operator String () const { return String(str, length, RTL_TEXTENCODING_ASCII_US); }
+ operator const sal_Char * () const { return str; }
+};
+
+#define IMPLEMENT_CONSTASCII_STRING( name, string ) \
+ _ConstAsciiString_ const name = { sizeof(string)-1, string }
+
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_GENERAL, "Syntax error in SQL expression");
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_GENERAL_HINT, "before \"#\" expression." );
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_VALUE_NO_LIKE, "The value # can not be used with LIKE!");
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_FIELD_NO_LIKE, "LIKE can not be used with this field!");
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_INVALID_COMPARE, "The entered criterion can not be compared with this field!");
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_INVALID_STRING_COMPARE, "The field can not be compared with a string!");
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_INVALID_DATE_COMPARE, "The field can not be compared with a date!");
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_INVALID_REAL_COMPARE, "The field can not be compared with a floating point number!");
+IMPLEMENT_CONSTASCII_STRING(ERROR_STR_INVALID_INT_COMPARE, "The field can not be compared with a number!");
+
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_LIKE, "LIKE");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_NOT, "NOT");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_NULL, "NULL");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_TRUE, "TRUE");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_FALSE, "FALSE");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_IS, "IS");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_BETWEEN, "BETWEEN");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_OR, "OR");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_AND, "AND");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_AVG, "AVG");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_COUNT, "COUNT");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_MAX, "MAX");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_MIN, "MIN");
+IMPLEMENT_CONSTASCII_STRING(KEY_STR_SUM, "SUM");
+
+IMPLEMENT_CONSTASCII_STRING(FIELD_STR_LOCALE, "Locale");
+IMPLEMENT_CONSTASCII_STRING(FIELD_STR_REALNAME, "RealName");
+IMPLEMENT_CONSTASCII_STRING(FIELD_STR_FORMATKEY, "FormatKey");
+IMPLEMENT_CONSTASCII_STRING(FIELD_STR_NAME, "Name");
+IMPLEMENT_CONSTASCII_STRING(FIELD_STR_TYPE, "Type");
+IMPLEMENT_CONSTASCII_STRING(FIELD_STR_NULLDATE, "NullDate");
+
+IMPLEMENT_CONSTASCII_STRING(STR_SQL_TOKEN, "SQL_TOKEN_");
+
+//==========================================================================
+//= OParseContext
+//==========================================================================
+DBG_NAME(OParseContext);
+//-----------------------------------------------------------------------------
+OParseContext::OParseContext()
+{
+ DBG_CTOR(OParseContext,NULL);
+}
+
+//-----------------------------------------------------------------------------
+OParseContext::~OParseContext()
+{
+ DBG_DTOR(OParseContext,NULL);
+}
+
+//-----------------------------------------------------------------------------
+String OParseContext::getErrorMessage(ErrorCode _eCode) const
+{
+ String aMsg;
+ switch (_eCode)
+ {
+ case ERROR_GENERAL: aMsg = ERROR_STR_GENERAL; break;
+ case ERROR_GENERAL_HINT: aMsg = ERROR_STR_GENERAL_HINT; break;
+ case ERROR_VALUE_NO_LIKE: aMsg = ERROR_STR_VALUE_NO_LIKE; break;
+ case ERROR_FIELD_NO_LIKE: aMsg = ERROR_STR_FIELD_NO_LIKE; break;
+ case ERROR_INVALID_COMPARE: aMsg = ERROR_STR_INVALID_COMPARE; break;
+ case ERROR_INVALID_INT_COMPARE: aMsg = ERROR_STR_INVALID_INT_COMPARE; break;
+ case ERROR_INVALID_STRING_COMPARE: aMsg = ERROR_STR_INVALID_STRING_COMPARE; break;
+ case ERROR_INVALID_DATE_COMPARE: aMsg = ERROR_STR_INVALID_DATE_COMPARE; break;
+ case ERROR_INVALID_REAL_COMPARE: aMsg = ERROR_STR_INVALID_REAL_COMPARE; break;
+ }
+ return aMsg;
+}
+
+//-----------------------------------------------------------------------------
+ByteString OParseContext::getIntlKeywordAscii(InternationalKeyCode _eKey) const
+{
+ ByteString aKeyword;
+ switch (_eKey)
+ {
+ case KEY_LIKE: aKeyword = KEY_STR_LIKE; break;
+ case KEY_NOT: aKeyword = KEY_STR_NOT; break;
+ case KEY_NULL: aKeyword = KEY_STR_NULL; break;
+ case KEY_TRUE: aKeyword = KEY_STR_TRUE; break;
+ case KEY_FALSE: aKeyword = KEY_STR_FALSE; break;
+ case KEY_IS: aKeyword = KEY_STR_IS; break;
+ case KEY_BETWEEN: aKeyword = KEY_STR_BETWEEN; break;
+ case KEY_OR: aKeyword = KEY_STR_OR; break;
+ case KEY_AND: aKeyword = KEY_STR_AND; break;
+ case KEY_AVG: aKeyword = KEY_STR_AVG; break;
+ case KEY_COUNT: aKeyword = KEY_STR_COUNT; break;
+ case KEY_MAX: aKeyword = KEY_STR_MAX; break;
+ case KEY_MIN: aKeyword = KEY_STR_MIN; break;
+ case KEY_SUM: aKeyword = KEY_STR_SUM; break;
+ }
+ return aKeyword;
+}
+
+//-----------------------------------------------------------------------------
+OParseContext::InternationalKeyCode OParseContext::getIntlKeyCode(const ByteString& rToken) const
+{
+ static OParseContext::InternationalKeyCode Intl_TokenID[] =
+ {
+ KEY_LIKE, KEY_NOT, KEY_NULL, KEY_TRUE,
+ KEY_FALSE, KEY_IS, KEY_BETWEEN, KEY_OR,
+ KEY_AND, KEY_AVG, KEY_COUNT, KEY_MAX,
+ KEY_MIN, KEY_SUM
+ };
+
+ sal_uInt32 nCount = sizeof Intl_TokenID / sizeof Intl_TokenID[0];
+ for (sal_uInt32 i = 0; i < nCount; i++)
+ {
+ ByteString aKey = getIntlKeywordAscii(Intl_TokenID[i]);
+ if (rToken.EqualsIgnoreCaseAscii(aKey))
+ return Intl_TokenID[i];
+ }
+
+ return KEY_NONE;
+}
+
+//------------------------------------------------------------------------------
+const International& OParseContext::getDefaultInternational()
+{
+ static International aIntl(LANGUAGE_ENGLISH_US);
+ static BOOL bInitialized = FALSE;
+ if (!bInitialized)
+ { // ensure that the two members we're interested in are really set
+ // (if the system doesn't know the locale en_US aIntl would be initialized with the
+ // system language which may be anything - which we don't want ...)
+ // 74342 - 21.03.00 - FS
+ aIntl.SetNumThousandSep(',');
+ aIntl.SetNumDecimalSep('.');
+ bInitialized = TRUE;
+ }
+ return aIntl;
+}
+
+//==========================================================================
+//= misc
+//==========================================================================
+// Der (leider globale) yylval fuer die Uebergabe von
+// Werten vom Scanner an den Parser. Die globale Variable
+// wird nur kurzzeitig verwendet, der Parser liest die Variable
+// sofort nach dem Scanner-Aufruf in eine gleichnamige eigene
+// Member-Variable.
+
+const double fMilliSecondsPerDay = 86400000.0;
+
+//------------------------------------------------------------------------------
+Date getNULLDate(const Reference< ::com::sun::star::util::XNumberFormatsSupplier > &xSupplier)
+{
+ DBG_ASSERT(xSupplier.is(), "getNULLDate : the formatter doesn't implement a supplier !");
+ if (xSupplier.is())
+ {
+ try
+ {
+ // get the null date
+ ::com::sun::star::util::Date aDate;
+ xSupplier->getNumberFormatSettings()->getPropertyValue(FIELD_STR_NULLDATE) >>= aDate;
+ return Date(aDate.Day, aDate.Month, aDate.Year);
+ }
+ catch ( ... )
+ {
+ }
+ }
+
+ return Date(1,1,1900);
+}
+
+//------------------------------------------------------------------------------
+Any getNumberFormatProperty(const Reference< ::com::sun::star::util::XNumberFormatsSupplier > &xSupplier,
+ sal_Int32 nKey,
+ const rtl::OUString& aPropertyName)
+{
+ DBG_ASSERT(xSupplier.is(), "getNumberFormatProperty : the formatter doesn't implement a supplier !");
+ Reference< ::com::sun::star::util::XNumberFormats > xFormats = xSupplier->getNumberFormats();
+
+ if (xFormats.is())
+ {
+ try
+ {
+ Reference< XPropertySet > xProperties(xFormats->getByKey(nKey));
+ return xProperties->getPropertyValue(aPropertyName);
+ }
+ catch( ... )
+ {
+ }
+ }
+ return Any();
+}
+
+// date time conversion
+//------------------------------------------------------------------
+DateTime ToDateTime(const Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xSupplier,
+ const double& fSbxDate)
+{
+
+ long nDays = (long)fSbxDate;
+ long nMSeconds = long((fSbxDate - (double)nDays) * fMilliSecondsPerDay + 0.5);
+
+ // Datum:
+ DateTime x(getNULLDate(xSupplier));
+
+ if (nDays >= 0)
+ x += (sal_uInt32)nDays;
+ else
+ x -= (sal_uInt32)(-nDays);
+
+ // Zeit:
+ x.MakeTimeFromMS(nMSeconds);
+ if (x.GetTime() < 0)
+ x += Time(23,59,59,99);
+ return x;
+}
+
+//------------------------------------------------------------------
+double ToDouble(const Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xSupplier, const Date& rDate)
+{
+ long nDays = 0;
+ Date aNullDate(getNULLDate(xSupplier));
+ if (aNullDate >= rDate)
+ {
+ nDays = (long)(aNullDate - rDate);
+ nDays *= -1;
+ }
+ else
+ nDays = (long)(rDate - aNullDate);
+
+ return (double)nDays;
+}
+
+//------------------------------------------------------------------
+double ToDouble(const Time& rTime)
+{
+ return (double)rTime.GetMSFromTime() / fMilliSecondsPerDay;
+}
+
+//------------------------------------------------------------------
+Date ToDate(const Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xSupplier, const double& fSbxDate)
+{
+ // count the days
+ long nDays = (long)fSbxDate;
+ Date aNullDate(getNULLDate(xSupplier));
+
+ if (nDays >= 0)
+ aNullDate += (sal_uInt32)nDays;
+ else
+ aNullDate -= (sal_uInt32)(-nDays);
+
+ return aNullDate;
+}
+
+//------------------------------------------------------------------
+Time ToTime(const double& fSbxDate)
+{
+ long nDays = (long)fSbxDate;
+ long nMSeconds = long((fSbxDate - (double)nDays) * fMilliSecondsPerDay + 0.5);
+
+ Time x;
+ x.MakeTimeFromMS(nMSeconds);
+ if (x.GetTime() < 0)
+ x += Time(23,59,59,99);
+ return x;
+}
+
+//------------------------------------------------------------------
+String ToDateString(const Date& rDate)
+{
+ sal_Char s[11];
+ sprintf(s,"%04d-%02d-%02d",
+ (int)rDate.GetYear(),
+ (int)rDate.GetMonth(),
+ (int)rDate.GetDay());
+ s[10] = 0;
+ return String::CreateFromAscii(s);
+}
+
+//------------------------------------------------------------------
+String ToTimeString(const Time& rTime)
+{
+ sal_Char s[9];
+ sprintf(s,"%02d:%02d:%02d",
+ (int)rTime.GetHour(),
+ (int)rTime.GetMin(),
+ (int)rTime.GetSec());
+ s[8] = 0;
+ return String::CreateFromAscii(s);
+}
+
+//------------------------------------------------------------------
+String ToDateTimeString(const DateTime& rDateTime)
+{
+ String aTemp(ToDateString(rDateTime));
+ aTemp += String::CreateFromAscii(" ");
+ aTemp += ToTimeString(rDateTime);
+ return aTemp;
+}
+
+
+//------------------------------------------------------------------
+String ConvertLikeToken(const OSQLParseNode* pTokenNode, const OSQLParseNode* pEscapeNode, sal_Bool bInternational)
+{
+ String aMatchStr;
+ if (pTokenNode->isToken())
+ {
+ char cEscape = 0;
+ if (pEscapeNode->count())
+ cEscape = pEscapeNode->getChild(1)->getTokenValue().GetChar(0);
+
+ // Platzhalter austauschen
+ aMatchStr = pTokenNode->getTokenValue();
+ sal_uInt16 nLen = aMatchStr.Len();
+ const char* sSearch = bInternational ? "%_" : "*?";
+ const char* sReplace = bInternational ? "*?" : "%_";
+ for (sal_uInt16 i = 0; i < nLen; i++)
+ {
+ char c = aMatchStr.GetChar(i);
+ if (c == sSearch[0] || c == sSearch[1])
+ {
+ if (i > 0 && aMatchStr.GetChar(i-1) == cEscape)
+ continue;
+ else if (c == sSearch[0])
+ aMatchStr.SetChar(i,sReplace[0]);
+ else
+ aMatchStr.SetChar(i,sReplace[1]);
+ }
+ }
+ }
+ return aMatchStr;
+}
+
+//==========================================================================
+//= OSQLParser
+//==========================================================================
+DBG_NAME(OSQLParser);
+
+sal_uInt32 OSQLParser::s_nRuleIDs[OSQLParseNode::rule_count + 1];
+OParseContext OSQLParser::s_aDefaultContext;
+
+sal_Int32 OSQLParser::s_nRefCount = 0;
+::osl::Mutex OSQLParser::s_aMutex;
+OSQLScanner* OSQLParser::s_pScanner = 0;
+OSQLParseNodes* OSQLParser::s_pGarbageCollector = 0;
+
+//-----------------------------------------------------------------------------
+OSQLParser::OSQLParser(OParseContext* _pContext)
+ :m_pContext(_pContext)
+ ,m_pParseTree(NULL)
+ ,m_pIntl(NULL)
+ ,m_nFormatKey(0)
+{
+ DBG_CTOR(OSQLParser,NULL);
+
+ xxx_pGLOBAL_SQLPARSER = this;
+
+#ifdef SQLYYDEBUG
+#ifdef SQLYYDEBUG_ON
+ SQLyydebug = 1;
+#endif
+#endif
+
+ ::osl::MutexGuard aGuard(s_aMutex);
+ // do we have to initialize the data
+ if (s_nRefCount == 0)
+ {
+ s_pScanner = new OSQLScanner();
+ s_pScanner->setScanner();
+ s_pGarbageCollector = new OSQLParseNodes();
+
+ // auf 0 zuruecksetzen
+ memset(OSQLParser::s_nRuleIDs,0,sizeof(sal_uInt16) * OSQLParseNode::rule_count+1);
+ }
+ ++s_nRefCount;
+
+ if (m_pContext == NULL)
+ // take the default context
+ m_pContext = &s_aDefaultContext;
+}
+
+//-----------------------------------------------------------------------------
+OSQLParser::~OSQLParser()
+{
+ {
+ ::osl::MutexGuard aGuard(s_aMutex);
+ DBG_ASSERT(s_nRefCount > 0, "OSQLParser::~OSQLParser() : suspicious call : have a refcount of 0 !");
+ if (!--s_nRefCount)
+ {
+ s_pScanner->setScanner(sal_True);
+ delete s_pScanner;
+ s_pScanner = NULL;
+
+ delete s_pGarbageCollector;
+ s_pGarbageCollector = NULL;
+ }
+ }
+
+ delete m_pIntl;
+
+ DBG_DTOR(OSQLParser,NULL);
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParser::parseTree(String& rErrorMessage,
+ const String& rStatement,
+ sal_Bool bInternational)
+{
+ DBG_CHKTHIS(OSQLParser,NULL);
+
+ // Guard the parsing
+ ::osl::MutexGuard aGuard(s_aMutex);
+
+ // defines how to scan
+ s_pScanner->SetRule(s_pScanner->GetSQLRule()); // initial
+ s_pScanner->prepareScan(rStatement, m_pContext, bInternational);
+
+ SQLyylval.pParseNode = NULL;
+ // SQLyypvt = NULL;
+ m_pParseTree = NULL;
+ m_sErrorMessage.Erase();
+
+ // ... und den Parser anwerfen ...
+ if (SQLyyparse() != 0)
+ {
+ // only set the error message, if it's not already set
+ if (!m_sErrorMessage.Len())
+ m_sErrorMessage = s_pScanner->getErrorMessage();
+ if (!m_sErrorMessage.Len())
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_GENERAL);
+
+ rErrorMessage = m_sErrorMessage;
+
+ // clear the garbage collector
+ while (!s_pGarbageCollector->empty())
+ {
+ OSQLParseNode* pNode = *s_pGarbageCollector->begin();
+ while (pNode->getParent())
+ pNode = pNode->getParent();
+ delete pNode;
+ }
+ return NULL;
+ }
+ else
+ {
+ s_pGarbageCollector->clear();
+
+ // Das Ergebnis liefern (den Root Parse Node):
+
+ // DBG_ASSERT(Sdbyyval.pParseNode != NULL,"OSQLParser: Parser hat keinen ParseNode geliefert");
+ // return Sdbyyval.pParseNode;
+ // geht nicht wegen Bug in MKS YACC-erzeugtem Code (es wird ein falscher ParseNode
+ // geliefert).
+
+ // Stattdessen setzt die Parse-Routine jetzt den Member pParseTree
+ // - einfach diesen zurueckliefern:
+ DBG_ASSERT(m_pParseTree != NULL,"OSQLParser: Parser hat keinen ParseTree geliefert");
+ return m_pParseTree;
+ }
+}
+
+static char* __READONLY_DATA PREDICATE_CHECK = "PREDICATE ";
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParser::predicateTree(String& rErrorMessage, const String& rStatement,
+ const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
+ const Reference< XPropertySet > & xField)
+{
+ DBG_CHKTHIS(OSQLParser,NULL);
+
+ // mutex for parsing
+ static ::osl::Mutex aMutex;
+
+ // Guard the parsing
+ ::osl::MutexGuard aGuard(s_aMutex);
+
+ // reset the parser
+ if (!m_pIntl)
+ m_pIntl = new International(m_pContext->getDefaultInternational());
+
+ m_xField = xField;
+ m_xFormatter = xFormatter;
+
+ if (m_xField.is())
+ {
+ sal_Int32 nType=0;
+ try
+ {
+ // get the field name
+ rtl::OUString aString;
+
+ // retrieve the fields name
+ // #75243# use the RealName of the column if there is any otherwise the name which could be the alias
+ // of the field
+ if (m_xField->getPropertySetInfo()->hasPropertyByName(FIELD_STR_REALNAME))
+ m_xField->getPropertyValue(FIELD_STR_REALNAME) >>= aString;
+ else
+ m_xField->getPropertyValue(FIELD_STR_NAME) >>= aString;
+
+ m_sFieldName = aString;
+
+ // get the field format key
+ m_xField->getPropertyValue(FIELD_STR_FORMATKEY) >>= m_nFormatKey;
+
+ // get the field type
+ m_xField->getPropertyValue(FIELD_STR_TYPE) >>= nType;
+ }
+ catch ( ... )
+ {
+ }
+
+ if (m_nFormatKey && m_xFormatter.is())
+ {
+ Any aValue = getNumberFormatProperty(m_xFormatter->getNumberFormatsSupplier(), m_nFormatKey, FIELD_STR_LOCALE);
+ DBG_ASSERT(aValue.getValueType() == ::getCppuType((const ::com::sun::star::lang::Locale*)0), "OSQLParser::PredicateTree : invalid language property !");
+
+ if (aValue.getValueType() == ::getCppuType((const ::com::sun::star::lang::Locale*)0))
+ {
+ com::sun::star::lang::Locale aLocale;
+ aValue >>= aLocale;
+ *m_pIntl = International(ConvertIsoNamesToLanguage(aLocale.Language.getStr(),
+ aLocale.Country.getStr()));
+ }
+ }
+ else
+ *m_pIntl = m_pContext->getDefaultInternational();
+
+ switch (nType)
+ {
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ s_pScanner->SetRule(s_pScanner->GetDATERule());
+ break;
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ s_pScanner->SetRule(s_pScanner->GetSTRINGRule());
+ break;
+ default:
+ if (m_pIntl->GetNumDecimalSep() == ',')
+ s_pScanner->SetRule(s_pScanner->GetGERRule());
+ else
+ s_pScanner->SetRule(s_pScanner->GetENGRule());
+ }
+
+ }
+ else
+ s_pScanner->SetRule(s_pScanner->GetSQLRule());
+
+ s_pScanner->prepareScan(rStatement, m_pContext, sal_True);
+
+ SQLyylval.pParseNode = NULL;
+ // SQLyypvt = NULL;
+ m_pParseTree = NULL;
+ m_sErrorMessage.Erase();
+
+ // ... und den Parser anwerfen ...
+ if (SQLyyparse() != 0)
+ {
+ m_sFieldName.Erase();
+ m_xField = NULL;
+ m_xFormatter = NULL;
+ m_nFormatKey = 0;
+
+ if (!m_sErrorMessage.Len())
+ m_sErrorMessage = s_pScanner->getErrorMessage();
+ if (!m_sErrorMessage.Len())
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_GENERAL);
+
+ rErrorMessage = m_sErrorMessage;
+
+ // clear the garbage collector
+ while (!s_pGarbageCollector->empty())
+ {
+ OSQLParseNode* pNode = *s_pGarbageCollector->begin();
+ while (pNode->getParent())
+ pNode = pNode->getParent();
+ delete pNode;
+ }
+ return NULL;
+ }
+ else
+ {
+ s_pGarbageCollector->clear();
+
+ m_sFieldName.Erase();
+ m_xField = NULL;
+ m_xFormatter = NULL;
+ m_nFormatKey = 0;
+
+ // Das Ergebnis liefern (den Root Parse Node):
+
+ // Stattdessen setzt die Parse-Routine jetzt den Member pParseTree
+ // - einfach diesen zurueckliefern:
+ DBG_ASSERT(m_pParseTree != NULL,"OSQLParser: Parser hat keinen ParseTree geliefert");
+ return m_pParseTree;
+ }
+}
+
+//-----------------------------------------------------------------------------
+ByteString OSQLParser::TokenIDToStr(sal_uInt32 nTokenID, OParseContext* pContext)
+{
+ ByteString aStr;
+ if (pContext)
+ aStr = pContext->getIntlKeywordAscii((OParseContext::InternationalKeyCode)nTokenID);
+
+ if (!aStr.Len())
+ {
+ aStr = yytname[YYTRANSLATE(nTokenID)];
+ if(aStr.EqualsIgnoreCaseAscii("SQL_TOKEN_",0,10))
+ aStr.Erase(0,10);
+ }
+ return aStr;
+}
+
+//-----------------------------------------------------------------------------
+/*sal_uInt32 OSQLParser::StrToTokenID(const ByteString & rName)
+{
+ ByteString aName;
+ if (rName.IsAlphaNumericAscii())
+ aName = rName;
+ else
+ {
+ aName = "'";
+ aName += rName;
+ aName += "'";
+ }
+
+ // Gewuenschten Token-Namen suchen:
+ for (sal_uInt32 i = 0; i < SQLyyntoken; i++)
+ {
+ if (aName == TokenTypes[i].name)
+ return TokenTypes[i].token;
+ }
+
+ // Nicht gefunden
+ return 0;
+}*/
+
+//-----------------------------------------------------------------------------
+String OSQLParser::RuleIDToStr(sal_uInt32 nRuleID)
+{
+ OSL_ENSHURE(nRuleID >= (sizeof yytname/sizeof yytname[0]), "Invalid nRuleId!");
+ return String::CreateFromAscii(yytname[nRuleID]);
+}
+
+//-----------------------------------------------------------------------------
+sal_uInt32 OSQLParser::StrToRuleID(const ByteString & rValue)
+{
+ // In yysvar nach dem angegebenen Namen suchen, den ::com::sun::star::sdbcx::Index zurueckliefern
+ // (oder 0, wenn nicht gefunden)
+ static sal_Int32 nLen = sizeof(yytname)/sizeof(yytname[0]);
+ for (sal_uInt32 i = YYTRANSLATE(SQL_TOKEN_INVALIDSYMBOL); i < (nLen-1); i++)
+ {
+ if (yytname && rValue == yytname[i])
+ return i;
+ }
+
+ // Nicht gefunden
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+sal_uInt32 OSQLParser::RuleID(OSQLParseNode::Rule eRule)
+{
+ if (!s_nRuleIDs[eRule])
+ {
+ switch (eRule)
+ {
+ case OSQLParseNode::select_statement:
+ s_nRuleIDs[eRule] = StrToRuleID("select_statement"); break;
+ case OSQLParseNode::from_clause:
+ s_nRuleIDs[eRule] = StrToRuleID("from_clause"); break;
+ case OSQLParseNode::table_ref_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("table_ref_commalist"); break;
+ case OSQLParseNode::table_exp:
+ s_nRuleIDs[eRule] = StrToRuleID("table_exp"); break;
+ case OSQLParseNode::table_ref:
+ s_nRuleIDs[eRule] = StrToRuleID("table_ref"); break;
+ case OSQLParseNode::table_name:
+ s_nRuleIDs[eRule] = StrToRuleID("table_name"); break;
+ case OSQLParseNode::opt_column_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("opt_column_commalist"); break;
+ case OSQLParseNode::column_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("column_commalist"); break;
+ case OSQLParseNode::column_ref_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("column_ref_commalist"); break;
+ case OSQLParseNode::column_ref:
+ s_nRuleIDs[eRule] = StrToRuleID("column_ref"); break;
+ case OSQLParseNode::opt_order_by_clause:
+ s_nRuleIDs[eRule] = StrToRuleID("opt_order_by_clause"); break;
+ case OSQLParseNode::ordering_spec_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("ordering_spec_commalist"); break;
+ case OSQLParseNode::ordering_spec:
+ s_nRuleIDs[eRule] = StrToRuleID("ordering_spec"); break;
+ case OSQLParseNode::opt_asc_desc:
+ s_nRuleIDs[eRule] = StrToRuleID("opt_asc_desc"); break;
+ case OSQLParseNode::where_clause:
+ s_nRuleIDs[eRule] = StrToRuleID("where_clause"); break;
+ case OSQLParseNode::opt_where_clause:
+ s_nRuleIDs[eRule] = StrToRuleID("opt_where_clause"); break;
+ case OSQLParseNode::search_condition:
+ s_nRuleIDs[eRule] = StrToRuleID("search_condition"); break;
+ case OSQLParseNode::comparison_predicate:
+ s_nRuleIDs[eRule] = StrToRuleID("comparison_predicate"); break;
+ case OSQLParseNode::between_predicate:
+ s_nRuleIDs[eRule] = StrToRuleID("between_predicate"); break;
+ case OSQLParseNode::like_predicate:
+ s_nRuleIDs[eRule] = StrToRuleID("like_predicate"); break;
+ case OSQLParseNode::opt_escape:
+ s_nRuleIDs[eRule] = StrToRuleID("opt_escape"); break;
+ case OSQLParseNode::test_for_null:
+ s_nRuleIDs[eRule] = StrToRuleID("test_for_null"); break;
+ case OSQLParseNode::scalar_exp_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("scalar_exp_commalist"); break;
+ case OSQLParseNode::scalar_exp:
+ s_nRuleIDs[eRule] = StrToRuleID("scalar_exp"); break;
+ case OSQLParseNode::parameter_ref:
+ s_nRuleIDs[eRule] = StrToRuleID("parameter_ref"); break;
+ case OSQLParseNode::parameter:
+ s_nRuleIDs[eRule] = StrToRuleID("parameter"); break;
+ case OSQLParseNode::general_set_fct:
+ s_nRuleIDs[eRule] = StrToRuleID("general_set_fct"); break;
+ case OSQLParseNode::range_variable:
+ s_nRuleIDs[eRule] = StrToRuleID("range_variable"); break;
+ case OSQLParseNode::column:
+ s_nRuleIDs[eRule] = StrToRuleID("column"); break;
+ case OSQLParseNode::delete_statement_positioned:
+ s_nRuleIDs[eRule] = StrToRuleID("delete_statement_positioned"); break;
+ case OSQLParseNode::delete_statement_searched:
+ s_nRuleIDs[eRule] = StrToRuleID("delete_statement_searched"); break;
+ case OSQLParseNode::update_statement_positioned:
+ s_nRuleIDs[eRule] = StrToRuleID("update_statement_positioned"); break;
+ case OSQLParseNode::update_statement_searched:
+ s_nRuleIDs[eRule] = StrToRuleID("update_statement_searched"); break;
+ case OSQLParseNode::assignment_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("assignment_commalist"); break;
+ case OSQLParseNode::assignment:
+ s_nRuleIDs[eRule] = StrToRuleID("assignment"); break;
+ case OSQLParseNode::values_or_query_spec:
+ s_nRuleIDs[eRule] = StrToRuleID("values_or_query_spec"); break;
+ case OSQLParseNode::insert_statement:
+ s_nRuleIDs[eRule] = StrToRuleID("insert_statement"); break;
+ case OSQLParseNode::insert_atom_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("insert_atom_commalist"); break;
+ case OSQLParseNode::insert_atom:
+ s_nRuleIDs[eRule] = StrToRuleID("insert_atom"); break;
+ case OSQLParseNode::predicate_check:
+ s_nRuleIDs[eRule] = StrToRuleID("predicate_check"); break;
+ case OSQLParseNode::qualified_join:
+ s_nRuleIDs[eRule] = StrToRuleID("qualified_join"); break;
+ case OSQLParseNode::cross_union:
+ s_nRuleIDs[eRule] = StrToRuleID("cross_union"); break;
+ case OSQLParseNode::select_sublist:
+ s_nRuleIDs[eRule] = StrToRuleID("select_sublist"); break;
+ case OSQLParseNode::derived_column:
+ s_nRuleIDs[eRule] = StrToRuleID("derived_column"); break;
+ case OSQLParseNode::column_val:
+ s_nRuleIDs[eRule] = StrToRuleID("column_val"); break;
+ case OSQLParseNode::set_fct_spec:
+ s_nRuleIDs[eRule] = StrToRuleID("set_fct_spec"); break;
+ case OSQLParseNode::boolean_term:
+ s_nRuleIDs[eRule] = StrToRuleID("boolean_term"); break;
+ case OSQLParseNode::boolean_primary:
+ s_nRuleIDs[eRule] = StrToRuleID("boolean_primary"); break;
+ case OSQLParseNode::num_value_exp:
+ s_nRuleIDs[eRule] = StrToRuleID("num_value_exp"); break;
+ case OSQLParseNode::join_type:
+ s_nRuleIDs[eRule] = StrToRuleID("join_type"); break;
+ case OSQLParseNode::position_exp:
+ s_nRuleIDs[eRule] = StrToRuleID("position_exp"); break;
+ case OSQLParseNode::extract_exp:
+ s_nRuleIDs[eRule] = StrToRuleID("extract_exp"); break;
+ case OSQLParseNode::length_exp:
+ s_nRuleIDs[eRule] = StrToRuleID("length_exp"); break;
+ case OSQLParseNode::char_value_fct:
+ s_nRuleIDs[eRule] = StrToRuleID("char_value_fct"); break;
+ case OSQLParseNode::odbc_call_spec:
+ s_nRuleIDs[eRule] = StrToRuleID("odbc_call_spec"); break;
+ case OSQLParseNode::in_predicate:
+ s_nRuleIDs[eRule] = StrToRuleID("in_predicate"); break;
+ case OSQLParseNode::existence_test:
+ s_nRuleIDs[eRule] = StrToRuleID("existence_test"); break;
+ case OSQLParseNode::unique_test:
+ s_nRuleIDs[eRule] = StrToRuleID("unique_test"); break;
+ case OSQLParseNode::all_or_any_predicate:
+ s_nRuleIDs[eRule] = StrToRuleID("all_or_any_predicate"); break;
+ case OSQLParseNode::named_columns_join:
+ s_nRuleIDs[eRule] = StrToRuleID("named_columns_join"); break;
+ case OSQLParseNode::join_condition:
+ s_nRuleIDs[eRule] = StrToRuleID("join_condition"); break;
+ case OSQLParseNode::joined_table:
+ s_nRuleIDs[eRule] = StrToRuleID("joined_table"); break;
+ case OSQLParseNode::boolean_factor:
+ s_nRuleIDs[eRule] = StrToRuleID("boolean_factor"); break;
+ case OSQLParseNode::not:
+ s_nRuleIDs[eRule] = StrToRuleID("not"); break;
+ case OSQLParseNode::boolean_test:
+ s_nRuleIDs[eRule] = StrToRuleID("boolean_test"); break;
+ case OSQLParseNode::manipulative_statement:
+ s_nRuleIDs[eRule] = StrToRuleID("manipulative_statement"); break;
+ case OSQLParseNode::subquery:
+ s_nRuleIDs[eRule] = StrToRuleID("subquery"); break;
+ case OSQLParseNode::value_exp_commalist:
+ s_nRuleIDs[eRule] = StrToRuleID("value_exp_commalist"); break;
+ case OSQLParseNode::odbc_fct_spec:
+ s_nRuleIDs[eRule] = StrToRuleID("odbc_fct_spec"); break;
+ case OSQLParseNode::union_statement:
+ s_nRuleIDs[eRule] = StrToRuleID("union_statement"); break;
+ case OSQLParseNode::outer_join_type:
+ s_nRuleIDs[eRule] = StrToRuleID("outer_join_type"); break;
+ case OSQLParseNode::char_value_exp:
+ s_nRuleIDs[eRule] = StrToRuleID("char_value_exp"); break;
+ case OSQLParseNode::term:
+ s_nRuleIDs[eRule] = StrToRuleID("term"); break;
+ case OSQLParseNode::value_exp_primary:
+ s_nRuleIDs[eRule] = StrToRuleID("value_exp_primary"); break;
+ case OSQLParseNode::value_exp:
+ s_nRuleIDs[eRule] = StrToRuleID("value_exp"); break;
+ default:
+ DBG_ERROR("interner Fehler: Regel nicht bekannt, in OSQLParser::RuleID nachtragen!");
+ }
+ }
+ return s_nRuleIDs[(sal_uInt16)eRule];
+}
+
+//-----------------------------------------------------------------------------
+sal_Int16 OSQLParser::buildNode(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare)
+{
+ OSQLParseNode* pColumnRef = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(new OSQLInternalNode(m_sFieldName,SQL_NODE_NAME));
+ OSQLParseNode* pComp = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::comparison_predicate));
+ pComp->append(pColumnRef);
+ pComp->append(pCompare);
+ pComp->append(pLiteral);
+ pAppend->append(pComp);
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+sal_Int16 OSQLParser::buildNode_STR_NUM(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,OSQLParseNode*& pCompare)
+{
+ OSQLParseNode* pColumnRef = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(new OSQLInternalNode(m_sFieldName,SQL_NODE_NAME));
+ OSQLParseNode* pComp = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::comparison_predicate));
+ pComp->append(pColumnRef);
+ pComp->append(pCompare);
+
+ if (m_nFormatKey)
+ {
+ sal_Int16 nScale = 0;
+ try
+ {
+ Any aValue = getNumberFormatProperty(m_xFormatter->getNumberFormatsSupplier(),
+ m_nFormatKey, rtl::OUString::createFromAscii("Decimals"));
+ aValue >>= nScale;
+ }
+ catch ( ... )
+ {
+ }
+
+ int nErrno=0;
+ double dValue = SolarMath::StringToDouble(pLiteral->getTokenValue().GetBuffer(), *m_pIntl, nErrno);
+ String aValue;
+ SolarMath::DoubleToString(aValue, dValue, 'F', nScale, m_pIntl->GetNumDecimalSep(), sal_True);
+ pComp->append(new OSQLInternalNode(aValue,SQL_NODE_STRING));
+ }
+ else
+ pComp->append(new OSQLInternalNode(pLiteral->getTokenValue(),SQL_NODE_STRING));
+
+ pAppend->append(pComp);
+
+ delete pLiteral;
+ pLiteral = NULL;
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+sal_Int16 OSQLParser::buildNode_Date(const double& fValue, sal_Int16 nType, OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare)
+{
+ OSQLParseNode* pColumnRef = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref));
+ pColumnRef->append(new OSQLInternalNode(m_sFieldName,SQL_NODE_NAME));
+ OSQLParseNode* pComp = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::comparison_predicate));
+ pComp->append(pColumnRef);
+ pComp->append(pCompare);
+
+ OSQLParseNode* pNewNode = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::set_fct_spec));
+ pNewNode->append(new OSQLInternalNode(String::CreateFromAscii("{"), SQL_NODE_PUNCTUATION));
+ OSQLParseNode* pDateNode = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::odbc_fct_spec));
+ pNewNode->append(pDateNode);
+ pNewNode->append(new OSQLInternalNode(String::CreateFromAscii("}"), SQL_NODE_PUNCTUATION));
+
+ switch (nType)
+ {
+ case DataType::DATE:
+ {
+ Date aDate = ToDate(m_xFormatter->getNumberFormatsSupplier(), fValue);
+ String aString = ToDateString(aDate);
+ pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_D));
+ pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
+ break;
+ }
+ case DataType::TIME:
+ {
+ Time aTime = ToTime(fValue);
+ String aString = ToTimeString(aTime);
+ pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_T));
+ pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
+ break;
+ }
+ case DataType::TIMESTAMP:
+ {
+ DateTime aDateTime = ToDateTime(m_xFormatter->getNumberFormatsSupplier(), fValue);
+ if (aDateTime.GetMSFromTime() / fMilliSecondsPerDay)
+ {
+ String aString = ToDateTimeString(aDateTime);
+ pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_TS));
+ pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
+ }
+ else
+ {
+ pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_D));
+ pDateNode->append(new OSQLInternalNode(ToDateString(aDateTime), SQL_NODE_STRING));
+ }
+ break;
+ }
+ }
+
+ pComp->append(pNewNode);
+ pAppend->append(pComp);
+
+ delete pLiteral;
+ pLiteral = NULL;
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+sal_Int16 OSQLParser::buildLikeRule(OSQLParseNode*& pAppend, OSQLParseNode*& pLiteral, const OSQLParseNode* pEscape)
+{
+ sal_Int16 nErg = 0;
+ sal_Int32 nType = 0;
+
+ if (!m_xField.is())
+ return nErg;
+ try
+ {
+ Any aValue;
+ {
+ aValue = m_xField->getPropertyValue(FIELD_STR_TYPE);
+ aValue >>= nType;
+ }
+ }
+ catch ( ... )
+ {
+ return nErg;
+ }
+
+ switch (nType)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ if(pLiteral->isRule())
+ {
+ pAppend->append(pLiteral);
+ nErg = 1;
+ }
+ else
+ {
+ switch(pLiteral->getNodeType())
+ {
+ case SQL_NODE_STRING:
+ pLiteral->m_aNodeValue = ConvertLikeToken(pLiteral, pEscape, sal_False);
+ pAppend->append(pLiteral);
+ nErg = 1;
+ break;
+ case SQL_NODE_APPROXNUM:
+ if (m_xFormatter.is() && m_nFormatKey)
+ {
+ sal_Int16 nScale = 0;
+ try
+ {
+ Any aValue = getNumberFormatProperty(m_xFormatter->getNumberFormatsSupplier(),
+ m_nFormatKey, rtl::OUString::createFromAscii("Decimals"));
+ aValue >>= nScale;
+ }
+ catch ( ... )
+ {
+ }
+
+ int nErrno=0;
+ String aValue;
+ double dValue = SolarMath::StringToDouble(pLiteral->getTokenValue().GetBuffer(), OParseContext::getDefaultInternational(), nErrno);
+ SolarMath::DoubleToString(aValue, dValue, 'F', nScale, '.', sal_True);
+ pAppend->append(new OSQLInternalNode(aValue,SQL_NODE_STRING));
+ }
+ else
+ pAppend->append(new OSQLInternalNode(pLiteral->getTokenValue(),SQL_NODE_STRING));
+
+ delete pLiteral;
+ nErg = 1;
+ break;
+ default:
+ {
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_VALUE_NO_LIKE);
+ m_sErrorMessage.SearchAndReplace(String::CreateFromAscii("#1"),pLiteral->getTokenValue());
+ }
+ }
+ }
+ break;
+ default:
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_FIELD_NO_LIKE);
+ }
+ return nErg;
+}
+//-----------------------------------------------------------------------------
+sal_Int16 OSQLParser::buildStringNodes(OSQLParseNode*& pLiteral)
+{
+ if(!pLiteral)
+ return 1;
+
+ if(SQL_ISRULE(pLiteral,set_fct_spec) || SQL_ISRULE(pLiteral,general_set_fct) || SQL_ISRULE(pLiteral,column_ref)
+ || SQL_ISRULE(pLiteral,subquery))
+ return 1; // here I have a function that I can't transform into a string
+
+ if(pLiteral->getNodeType() == SQL_NODE_INTNUM || pLiteral->getNodeType() == SQL_NODE_APPROXNUM || pLiteral->getNodeType() == SQL_NODE_ACCESS_DATE)
+ {
+ OSQLParseNode* pParent = pLiteral->getParent();
+
+ OSQLParseNode* pNewNode = new OSQLInternalNode(pLiteral->getTokenValue(), SQL_NODE_STRING);
+ pParent->replace(pLiteral, pNewNode);
+ delete pLiteral;
+ pLiteral = NULL;
+ return 1;
+ }
+
+ for(sal_uInt32 i=0;i<pLiteral->count();++i)
+ {
+ OSQLParseNode* pChild = pLiteral->getChild(i);
+ buildStringNodes(pChild);
+ }
+ if(SQL_ISRULE(pLiteral,term) || SQL_ISRULE(pLiteral,value_exp_primary))
+ {
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_COMPARE);
+ return 0;
+ }
+ return 1;
+}
+//-----------------------------------------------------------------------------
+sal_Int16 OSQLParser::buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral)
+{
+ OSQLParseNode* pComp = new OSQLInternalNode(String('='), SQL_NODE_EQUAL);
+ return buildComparsionRule(pAppend,pLiteral,pComp);
+}
+
+//-----------------------------------------------------------------------------
+sal_Int16 OSQLParser::buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare)
+{
+ sal_Int16 nErg = 0;
+ if (m_xField.is())
+ {
+ sal_Int32 nType = 0;
+ try
+ {
+ Any aValue;
+ {
+ aValue = m_xField->getPropertyValue(FIELD_STR_TYPE);
+ aValue >>= nType;
+ }
+ }
+ catch ( ... )
+ {
+ return nErg;
+ }
+
+ if (pLiteral->isRule() && !SQL_ISRULE(pLiteral,value_exp))
+ {
+ switch(nType)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ if(!SQL_ISRULE(pLiteral,char_value_exp) && !buildStringNodes(pLiteral))
+ break;
+ default:
+ nErg = buildNode(pAppend,pLiteral,pCompare);
+ }
+ }
+ else
+ {
+ switch(pLiteral->getNodeType())
+ {
+ case SQL_NODE_STRING:
+ switch(nType)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ nErg = buildNode(pAppend,pLiteral,pCompare);
+ break;
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ if (m_xFormatter.is())
+ {
+ try
+ {
+ // do we have a date
+ double fValue = m_xFormatter->convertStringToNumber(m_nFormatKey, pLiteral->getTokenValue().GetBuffer());
+ nErg = buildNode_Date(fValue, nType, pAppend,pLiteral,pCompare);
+ }
+ catch ( ... )
+ {
+ try
+ {
+ Reference< ::com::sun::star::util::XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier();
+ Reference< ::com::sun::star::util::XNumberFormatTypes > xFormatTypes(xFormatSup->getNumberFormats(),UNO_QUERY);
+ if (xFormatTypes.is())
+ {
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames(m_pIntl->GetLanguage(), sLanguage, sCountry);
+ ::com::sun::star::lang::Locale aLocale(sLanguage.GetBuffer(),
+ sCountry.GetBuffer(),
+ rtl::OUString());
+
+ double fValue = m_xFormatter->convertStringToNumber(
+ xFormatTypes->getStandardFormat(::com::sun::star::util::NumberFormat::DATE, aLocale),
+ pLiteral->getTokenValue().GetBuffer());
+ nErg = buildNode_Date(fValue, nType, pAppend,pLiteral,pCompare);
+ }
+ else
+ {
+ nErg = -1;
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_DATE_COMPARE);
+ }
+
+ }
+ catch ( ... )
+ {
+ nErg = -1;
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_DATE_COMPARE);
+ }
+ }
+ }
+ else
+ nErg = buildNode(pAppend,pLiteral,pCompare);
+
+ break;
+ default:
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_DATE_COMPARE);
+ }
+ break;
+ case SQL_NODE_ACCESS_DATE:
+ switch(nType)
+ {
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ if (m_xFormatter.is())
+ {
+ try
+ {
+ // do we have a date
+ double fValue = m_xFormatter->convertStringToNumber(m_nFormatKey, pLiteral->getTokenValue().GetBuffer());
+ nErg = buildNode_Date(fValue, nType, pAppend,pLiteral,pCompare);
+ }
+ catch ( ... )
+ {
+ try
+ {
+ Reference< ::com::sun::star::util::XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier();
+ Reference< ::com::sun::star::util::XNumberFormatTypes > xFormatTypes(xFormatSup->getNumberFormats(),UNO_QUERY);
+ if (xFormatTypes.is())
+ {
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames(m_pIntl->GetLanguage(), sLanguage, sCountry);
+ ::com::sun::star::lang::Locale aLocale(sLanguage.GetBuffer(),
+ sCountry.GetBuffer(),
+ rtl::OUString());
+
+ double fValue = m_xFormatter->convertStringToNumber(
+ xFormatTypes->getStandardFormat(::com::sun::star::util::NumberFormat::DATE, aLocale),
+ pLiteral->getTokenValue().GetBuffer());
+ nErg = buildNode_Date(fValue, nType, pAppend,pLiteral,pCompare);
+ }
+ else
+ {
+ nErg = -1;
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_DATE_COMPARE);
+ }
+ }
+ catch ( ... )
+ {
+ nErg = -1;
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_DATE_COMPARE);
+ }
+ }
+ }
+ else
+ {
+ nErg = -1;
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_DATE_COMPARE);
+ }
+ break;
+ default:
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_DATE_COMPARE);
+ }
+ break;
+ case SQL_NODE_INTNUM:
+ switch(nType)
+ {
+ case DataType::BIT:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::INTEGER:
+ case DataType::BIGINT:
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ // kill thousand seperators if any
+ if (m_pIntl->GetNumDecimalSep() == ',' )
+ {
+ pLiteral->m_aNodeValue.SearchAndReplaceAll('.', String());
+ // and replace decimal
+ pLiteral->m_aNodeValue.SearchAndReplaceAll(',', '.');
+ }
+ else
+ pLiteral->m_aNodeValue.SearchAndReplaceAll(',', String());
+ nErg = buildNode(pAppend,pLiteral,pCompare);
+ break;
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ nErg = buildNode_STR_NUM(pAppend,pLiteral,pCompare);
+ break;
+ default:
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_INT_COMPARE);
+ }
+ break;
+ case SQL_NODE_APPROXNUM:
+ switch(nType)
+ {
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ if (inPredicateCheck())
+ {
+ // kill thousand seperators if any
+ if (m_pIntl->GetNumDecimalSep() == ',' )
+ {
+ pLiteral->m_aNodeValue.SearchAndReplaceAll('.', String());
+ // and replace decimal
+ pLiteral->m_aNodeValue.SearchAndReplaceAll(',', '.');
+ }
+ else
+ pLiteral->m_aNodeValue.SearchAndReplaceAll(',', String());
+ }
+ nErg = buildNode(pAppend,pLiteral,pCompare);
+ break;
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ nErg = buildNode_STR_NUM(pAppend,pLiteral,pCompare);
+ break;
+ case DataType::INTEGER:
+ default:
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_INVALID_REAL_COMPARE);
+ }
+ break;
+ }
+ }
+ if (!nErg)
+ --nErg;
+ }
+ if (!pCompare->getParent()) // I have no parent so I was not used and I must die :-)
+ delete pCompare;
+ return nErg;
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParser::reduceLiteral(OSQLParseNode*& pLiteral, sal_Bool bAppendBlank)
+{
+ DBG_ASSERT(pLiteral->isRule(), "This is no ::com::sun::star::chaos::Rule");
+ DBG_ASSERT(pLiteral->count() == 2, "OSQLParser::ReduceLiteral() Invalid count");
+ OSQLParseNode* pTemp = pLiteral;
+ String aValue;
+ if (bAppendBlank)
+ {
+ ((aValue = pLiteral->getChild(0)->getTokenValue()) += String(' ')) +=
+ pLiteral->getChild(1)->getTokenValue();
+ }
+ else
+ (aValue = pLiteral->getChild(0)->getTokenValue()) +=
+ pLiteral->getChild(1)->getTokenValue();
+
+ pLiteral = new OSQLInternalNode(aValue,SQL_NODE_STRING);
+ delete pTemp;
+}
+// -------------------------------------------------------------------------
+void OSQLParser::error(char *fmt)
+{
+ if(!m_sErrorMessage.Len())
+ {
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_GENERAL);
+ m_sErrorMessage.AppendAscii(": ");
+ m_sErrorMessage += m_pContext->getErrorMessage(OParseContext::ERROR_GENERAL_HINT);
+ m_sErrorMessage.SearchAndReplaceAscii("#",String::CreateFromAscii(fmt));
+ }
+}
+// -------------------------------------------------------------------------
+int OSQLParser::SQLlex()
+{
+ return s_pScanner->SQLlex();
+}
+/*------------------------------------------------------------------------
+
+ $Log: not supported by cvs2svn $
+ Revision 1.1 2000/07/25 10:39:29 oj
+ new revision
+
+ Revision 1.0 21.07.2000 12:27:34 oj
+------------------------------------------------------------------------*/
+
diff --git a/connectivity/source/parse/sqlflex.l b/connectivity/source/parse/sqlflex.l
new file mode 100644
index 000000000000..446ec2454aea
--- /dev/null
+++ b/connectivity/source/parse/sqlflex.l
@@ -0,0 +1,592 @@
+%{
+
+//--------------------------------------------------------------------------
+//
+// $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/connectivity/source/parse/sqlflex.l,v 1.1.1.1 2000-09-18 16:14:28 hr Exp $
+//
+// Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+//
+// First creation:
+// OJ
+//
+// Last change:
+// $Author: hr $ $Date: 2000-09-18 16:14:28 $ $Revision: 1.1.1.1 $
+//
+// Description:
+//
+//
+//--------------------------------------------------------------------------
+
+#define YY_EXIT 1 // YY_FATAL will not halt the application
+
+#ifndef _CSTDARG_
+#include <cstdarg> // std::va_list
+#endif
+
+#ifndef _INC_STRING
+#include <string.h>
+#endif
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+
+#ifndef _CONNECTIVITY_SQLINTERNALNODE_HXX
+#include "internalnode.hxx"
+#endif
+
+#ifndef _CONNECTIVITY_SQLYACC_HXX
+#define _CONNECTIVITY_SQLYACC_HXX
+
+#ifndef SQLYYDEBUG
+#define SQLYYDEBUG 1
+#endif
+
+#include "connectivity/sqlbison.hxx"
+#endif
+#ifndef _CONNECTIVITY_SQLSCAN_HXX
+#include "sqlscan.hxx"
+#endif
+#ifndef _OSL_DIAGNOSE_H_
+#include <osl/diagnose.h>
+#endif
+#ifndef _CONNECTIVITY_SQLPARSE_HXX
+#include <connectivity/sqlparse.hxx>
+#endif
+using namespace connectivity;
+
+//=============================================================================
+//
+// Erzeugung der Blaetter fuer die Token
+// Blaetter werden generell vom Lexer erzeugt
+
+static String aEmptyString;
+
+static int gatherString(int delim, int nTyp);
+static int gatherName(const char*);
+static int gatherNamePre(const char* );
+// has to be set before the parser starts
+OSQLScanner* xxx_pGLOBAL_SQLSCAN = NULL;
+
+#define SQL_NEW_NODE(text, token) \
+ SQLyylval.pParseNode = new OSQLInternalNode(text, token);
+
+#define SQL_NEW_KEYWORD(token) \
+ SQLyylval.pParseNode = new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, (token));
+
+#define SQL_NEW_NAME SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_NAME)
+#define SQL_NEW_INTNUM SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_INTNUM)
+#define SQL_NEW_APPROXNUM SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_APPROXNUM)
+#define SQL_NEW_STRING SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_STRING)
+#define SQL_NEW_COMPARISON SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_COMPARISON)
+#define SQL_NEW_AMMSC SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_AMMSC)
+#define SQL_NEW_DATE SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_ACCESS_DATE)
+
+#define YY_INPUT(buf,result,max_size) \
+{ \
+ buf[0] = xxx_pGLOBAL_SQLSCAN->SQLyygetc(); \
+ result = buf[0] != -1; \
+}
+
+#define YY_FATAL_ERROR(msg) \
+{ \
+ xxx_pGLOBAL_SQLSCAN->SQLyyerror(msg); \
+}
+
+//
+//=============================================================================
+
+%}
+%e 2500
+%n 2900
+%p 8500
+
+%s SQL
+%s PREDICATE_ENG
+%s PREDICATE_GER
+%s DATE
+%s STRING
+
+%option noyywrap
+%option never-interactive
+%%
+
+[Aa][Ll][Ll] {SQL_NEW_KEYWORD(SQL_TOKEN_ALL); return SQL_TOKEN_ALL; }
+[Aa][Ll][Tt][Ee][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_ALTER); return SQL_TOKEN_ALTER; }
+[Aa][Nn][Dd] {SQL_NEW_KEYWORD(SQL_TOKEN_AND); return SQL_TOKEN_AND; }
+[Aa][Nn][Yy] {SQL_NEW_KEYWORD(SQL_TOKEN_ANY); return SQL_TOKEN_ANY; }
+[Aa][Ss] {SQL_NEW_KEYWORD(SQL_TOKEN_AS); return SQL_TOKEN_AS; }
+[Aa][Ss][Cc] {SQL_NEW_KEYWORD(SQL_TOKEN_ASC); return SQL_TOKEN_ASC; }
+[Aa][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_AT); return SQL_TOKEN_AT; }
+[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_AUTHORIZATION); return SQL_TOKEN_AUTHORIZATION; }
+[Aa][Vv][Gg] {SQL_NEW_KEYWORD(SQL_TOKEN_AVG); return SQL_TOKEN_AVG; }
+
+[Bb][Ee][Tt][Ww][Ee][Ee][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_BETWEEN); return SQL_TOKEN_BETWEEN; }
+[Bb][Ii][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_BIT); return SQL_TOKEN_BIT; }
+[Bb][Ii][Tt]_[Ll][Ee][Nn][Gg][Tt][Hh] {SQL_NEW_KEYWORD(SQL_TOKEN_BIT_LENGTH); return SQL_TOKEN_BIT_LENGTH; }
+[Bb][Oo][Tt][Hh] {SQL_NEW_KEYWORD(SQL_TOKEN_BOTH); return SQL_TOKEN_BOTH; }
+[Bb][Yy] {SQL_NEW_KEYWORD(SQL_TOKEN_BY); return SQL_TOKEN_BY; }
+
+[Cc][Aa][Ll][Ll] {SQL_NEW_KEYWORD(SQL_TOKEN_CALL); return SQL_TOKEN_CALL; }
+[Cc][Aa][Ss][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_CAST); return SQL_TOKEN_CAST; }
+[Cc][Hh][Aa][Rr]([Aa][Cc][Tt][Ee][Rr])? {SQL_NEW_KEYWORD(SQL_TOKEN_CHARACTER); return SQL_TOKEN_CHARACTER; }
+[Cc][Hh][Aa][Rr]([Aa][Cc][Tt][Ee][Rr])?_[Ll][Ee][Nn][Gg][Tt][Hh] {SQL_NEW_KEYWORD(SQL_TOKEN_CHAR_LENGTH); return SQL_TOKEN_CHAR_LENGTH; }
+[Cc][Hh][Ee][Cc][Kk] {SQL_NEW_KEYWORD(SQL_TOKEN_CHECK); return SQL_TOKEN_CHECK; }
+[Cc][Oo][Ll][Ll][Aa][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_COLLATE); return SQL_TOKEN_COLLATE; }
+[Cc][Oo][Mm][Mm][Ii][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_COMMIT); return SQL_TOKEN_COMMIT; }
+[Cc][Oo][Nn][Tt][Ii][Nn][Uu][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_CONTINUE); return SQL_TOKEN_CONTINUE; }
+[Cc][Oo][Nn][Vv][Ee][Rr][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_CONVERT); return SQL_TOKEN_CONVERT; }
+[Cc][Oo][Uu][Nn][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_COUNT); return SQL_TOKEN_COUNT; }
+[Cc][Rr][Ee][Aa][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_CREATE); return SQL_TOKEN_CREATE; }
+[Cc][Rr][Oo][Ss][Ss] {SQL_NEW_KEYWORD(SQL_TOKEN_CROSS); return SQL_TOKEN_CROSS; }
+[Cc][Uu][Rr][Rr][Ee][Nn][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_CURRENT); return SQL_TOKEN_CURRENT; }
+[Cc][Uu][Rr][Rr][Ee][Nn][Tt]_[Dd][Aa][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_CURRENT_DATE); return SQL_TOKEN_CURRENT_DATE; }
+[Cc][Uu][Rr][Rr][Ee][Nn][Tt]_[Tt][Ii][Mm][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_CURRENT_TIME); return SQL_TOKEN_CURRENT_TIME; }
+[Cc][Uu][Rr][Rr][Ee][Nn][Tt]_[Tt][Ii][Mm][Ee][Ss][Tt][Aa][Mm][Pp] {SQL_NEW_KEYWORD(SQL_TOKEN_CURRENT_TIMESTAMP); return SQL_TOKEN_CURRENT_TIMESTAMP; }
+[Cc][Uu][Rr][Ss][Oo][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_CURSOR); return SQL_TOKEN_CURSOR; }
+
+[Dd] {SQL_NEW_KEYWORD(SQL_TOKEN_D); return SQL_TOKEN_D; }
+[Dd][Aa][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_DATE); return SQL_TOKEN_DATE; }
+[Dd][Aa][Yy] {SQL_NEW_KEYWORD(SQL_TOKEN_DAY); return SQL_TOKEN_DAY; }
+[Dd][Ee][Cc] {SQL_NEW_KEYWORD(SQL_TOKEN_DEC); return SQL_TOKEN_DEC; }
+[Dd][Ee][Cc][Ii][Mm][Aa][Ll] {SQL_NEW_KEYWORD(SQL_TOKEN_DECIMAL); return SQL_TOKEN_DECIMAL; }
+[Dd][Ee][Cc][Ll][Aa][Rr][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_DECLARE); return SQL_TOKEN_DECLARE; }
+[Dd][Ee][Ff][Aa][Uu][Ll][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_DEFAULT); return SQL_TOKEN_DEFAULT; }
+[Dd][Ee][Ll][Ee][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_DELETE); return SQL_TOKEN_DELETE; }
+[Dd][Ee][Ss][Cc] {SQL_NEW_KEYWORD(SQL_TOKEN_DESC); return SQL_TOKEN_DESC; }
+[Dd][Ii][Ss][Tt][Ii][Nn][Cc][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_DISTINCT); return SQL_TOKEN_DISTINCT; }
+[Dd][Oo][Uu][Bb][Ll][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_DOUBLE); return SQL_TOKEN_DOUBLE; }
+[Dd][Rr][Oo][Pp] {SQL_NEW_KEYWORD(SQL_TOKEN_DROP); return SQL_TOKEN_DROP; }
+
+[Ee][Ss][Cc][Aa][Pp][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_ESCAPE); return SQL_TOKEN_ESCAPE; }
+[Ee][Xx][Cc][Ee][Pp][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_EXCEPT); return SQL_TOKEN_EXCEPT; }
+[Ee][Xx][Ii][Ss][Tt][Ss] {SQL_NEW_KEYWORD(SQL_TOKEN_EXISTS); return SQL_TOKEN_EXISTS; }
+[Ee][Xx][Tt][Rr][Aa][Cc][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_EXTRACT); return SQL_TOKEN_EXTRACT; }
+
+[Ff][Aa][Ll][Ss][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_FALSE); return SQL_TOKEN_FALSE; }
+[Ff][Ee][Tt][Cc][Hh] {SQL_NEW_KEYWORD(SQL_TOKEN_FETCH); return SQL_TOKEN_FETCH; }
+[Ff][Ll][Oo][Aa][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_FLOAT); return SQL_TOKEN_FLOAT; }
+[Ff][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_FN); return SQL_TOKEN_FN; }
+[Ff][Oo][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_FOR); return SQL_TOKEN_FOR; }
+[Ff][Oo][Rr][Ee][Ii][Gg][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_FOREIGN); return SQL_TOKEN_FOREIGN; }
+[Ff][Oo][Uu][Nn][Dd] {SQL_NEW_KEYWORD(SQL_TOKEN_FOUND); return SQL_TOKEN_FOUND; }
+[Ff][Rr][Oo][Mm] {SQL_NEW_KEYWORD(SQL_TOKEN_FROM); return SQL_TOKEN_FROM; }
+[Ff][Uu][Ll][Ll] {SQL_NEW_KEYWORD(SQL_TOKEN_FULL); return SQL_TOKEN_FULL; }
+
+[Gg][Rr][Aa][Nn][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_GRANT); return SQL_TOKEN_GRANT; }
+[Gg][Rr][Oo][Uu][Pp] {SQL_NEW_KEYWORD(SQL_TOKEN_GROUP); return SQL_TOKEN_GROUP; }
+
+[Hh][Aa][Vv][Ii][Nn][Gg] {SQL_NEW_KEYWORD(SQL_TOKEN_HAVING); return SQL_TOKEN_HAVING; }
+[Hh][Oo][Uu][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_HOUR); return SQL_TOKEN_HOUR; }
+
+[Ii][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_IN); return SQL_TOKEN_IN; }
+[Ii][Nn][Nn][Ee][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_INNER); return SQL_TOKEN_INNER; }
+[Ii][Nn][Ss][Ee][Rr][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_INSERT); return SQL_TOKEN_INSERT; }
+[Ii][Nn][Tt]([Ee][Gg][Ee][Rr])? {SQL_NEW_KEYWORD(SQL_TOKEN_INTEGER); return SQL_TOKEN_INTEGER; }
+[Ii][Nn][Tt][Ee][Rr][Ss][Ee][Cc][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_INTERSECT); return SQL_TOKEN_INTERSECT; }
+[Ii][Nn][Tt][Oo] {SQL_NEW_KEYWORD(SQL_TOKEN_INTO); return SQL_TOKEN_INTO; }
+[Ii][Ss] {SQL_NEW_KEYWORD(SQL_TOKEN_IS); return SQL_TOKEN_IS; }
+
+[Jj][Oo][Ii][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_JOIN); return SQL_TOKEN_JOIN; }
+
+[Kk][Ee][Yy] {SQL_NEW_KEYWORD(SQL_TOKEN_KEY); return SQL_TOKEN_KEY; }
+
+[Ll][Ee][Aa][Dd][Ii][Nn][Gg] {SQL_NEW_KEYWORD(SQL_TOKEN_LEADING); return SQL_TOKEN_LEADING; }
+[Ll][Ee][Ff][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_LEFT); return SQL_TOKEN_LEFT; }
+[Ll][Ii][Kk][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_LIKE); return SQL_TOKEN_LIKE; }
+[Ll][Oo][Cc][Aa][Ll] {SQL_NEW_KEYWORD(SQL_TOKEN_LOCAL); return SQL_TOKEN_LOCAL; }
+[Ll][Oo][Ww][Ee][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_LOWER); return SQL_TOKEN_LOWER; }
+
+[Mm][Aa][Xx] {SQL_NEW_KEYWORD(SQL_TOKEN_MAX); return SQL_TOKEN_MAX; }
+[Mm][Ii][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_MIN); return SQL_TOKEN_MIN; }
+[Mm][Ii][Nn][Uu][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_MINUTE); return SQL_TOKEN_MINUTE; }
+[Mm][Oo][Nn][Tt][Hh] {SQL_NEW_KEYWORD(SQL_TOKEN_MONTH); return SQL_TOKEN_MONTH; }
+
+[Nn][Aa][Tt][Uu][Rr][Aa][LL] {SQL_NEW_KEYWORD(SQL_TOKEN_NATURAL); return SQL_TOKEN_NATURAL; }
+[Nn][Cc][Hh][Aa][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_NCHAR); return SQL_TOKEN_NCHAR; }
+[Nn][Oo][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_NOT); return SQL_TOKEN_NOT; }
+[Nn][Uu][Ll][Ll] {SQL_NEW_KEYWORD(SQL_TOKEN_NULL); return SQL_TOKEN_NULL; }
+[Nn][Uu][Mm][Ee][Rr][Ii][Cc] {SQL_NEW_KEYWORD(SQL_TOKEN_NUMERIC); return SQL_TOKEN_NUMERIC; }
+
+[Oo][Cc][Tt][Ee][Tt]_[Ll][Ee][Nn][Gg][Tt][Hh] {SQL_NEW_KEYWORD(SQL_TOKEN_OCTECT_LENGTH); return SQL_TOKEN_OCTECT_LENGTH; }
+[Oo][Ff] {SQL_NEW_KEYWORD(SQL_TOKEN_OF); return SQL_TOKEN_OF; }
+[Oo][Jj] {SQL_NEW_KEYWORD(SQL_TOKEN_OJ); return SQL_TOKEN_OJ; }
+[Oo][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_ON); return SQL_TOKEN_ON; }
+[Oo][Pp][Tt][Ii][Oo][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_OPTION); return SQL_TOKEN_OPTION; }
+[Oo][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_OR); return SQL_TOKEN_OR; }
+[Oo][Rr][Dd][Ee][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_ORDER); return SQL_TOKEN_ORDER; }
+[Oo][Uu][Tt][Ee][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_OUTER); return SQL_TOKEN_OUTER; }
+
+[Pp][Oo][Ss][Ii][Tt][Ii][Oo][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_POSITION); return SQL_TOKEN_POSITION; }
+[Pp][Rr][Ee][Cc][Ii][Ss][Ii][Oo][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_PRECISION); return SQL_TOKEN_PRECISION; }
+[Pp][Rr][Ii][Mm][Aa][Rr][Yy] {SQL_NEW_KEYWORD(SQL_TOKEN_PRIMARY); return SQL_TOKEN_PRIMARY; }
+[Pp][Rr][Ii][Vv][Ii][Ll][Ee][Gg][Ee][Ss] {SQL_NEW_KEYWORD(SQL_TOKEN_PRIVILEGES); return SQL_TOKEN_PRIVILEGES; }
+[Pp][Rr][Oo][Cc][Ee][Dd][Uu][Rr][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_PROCEDURE); return SQL_TOKEN_PROCEDURE; }
+[Pp][Uu][Bb][Ll][Ii][Cc] {SQL_NEW_KEYWORD(SQL_TOKEN_PUBLIC); return SQL_TOKEN_PUBLIC; }
+
+[Rr][Ee][Aa][Ll] {SQL_NEW_KEYWORD(SQL_TOKEN_REAL); return SQL_TOKEN_REAL; }
+[Rr][Ee][Ff][Ee][Rr][Ee][Nn][Cc][Ee][Ss] {SQL_NEW_KEYWORD(SQL_TOKEN_REFERENCES); return SQL_TOKEN_REFERENCES; }
+[Rr][Oo][Ll][Ll][Bb][Aa][Cc][Kk] {SQL_NEW_KEYWORD(SQL_TOKEN_ROLLBACK); return SQL_TOKEN_ROLLBACK; }
+[Rr][Ii][Gg][Hh][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_RIGHT); return SQL_TOKEN_RIGHT; }
+
+[Ss][Cc][Hh][Ee][Mm][Aa] {SQL_NEW_KEYWORD(SQL_TOKEN_SCHEMA); return SQL_TOKEN_SCHEMA; }
+[Ss][Ee][Cc][Ee][Oo][Nn][Dd] {SQL_NEW_KEYWORD(SQL_TOKEN_SECOND); return SQL_TOKEN_SECOND; }
+[Ss][Ee][Ll][Ee][Cc][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_SELECT); return SQL_TOKEN_SELECT; }
+[Ss][Ee][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_SET); return SQL_TOKEN_SET; }
+[Ss][Ii][Zz][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_SIZE); return SQL_TOKEN_SIZE; }
+[Ss][Mm][Aa][Ll][Ll][Ii][Nn][Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_SMALLINT); return SQL_TOKEN_SMALLINT; }
+[Ss][Oo][Mm][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_SOME); return SQL_TOKEN_SOME; }
+[Ss][Uu][Bb][Ss][Tt][Rr][Ii][Nn][Gg] {SQL_NEW_KEYWORD(SQL_TOKEN_SUBSTRING); return SQL_TOKEN_SUBSTRING; }
+[Ss][Uu][Mm] {SQL_NEW_KEYWORD(SQL_TOKEN_SUM); return SQL_TOKEN_SUM; }
+
+[Tt] {SQL_NEW_KEYWORD(SQL_TOKEN_T); return SQL_TOKEN_T; }
+[Tt][Aa][Bb][Ll][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_TABLE); return SQL_TOKEN_TABLE; }
+[Tt][Ii][Mm][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_TIME); return SQL_TOKEN_TIME; }
+[Tt][Ii][Mm][Ee][Ss][Tt][Aa][Mm][Pp] {SQL_NEW_KEYWORD(SQL_TOKEN_TIMESTAMP); return SQL_TOKEN_TIMESTAMP; }
+[Tt][Ii][Mm][Ee][Zz][Oo][Nn][Ee]_[Hh][Oo][Uu][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_TIMEZONE_HOUR); return SQL_TOKEN_TIMEZONE_HOUR; }
+[Tt][Ii][Mm][Ee][Zz][Oo][Nn][Ee]_[Mm][Ii][Nn][Uu][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_TIMEZONE_MINUTE); return SQL_TOKEN_TIMEZONE_MINUTE; }
+[Tt][Oo] {SQL_NEW_KEYWORD(SQL_TOKEN_TO); return SQL_TOKEN_TO; }
+[Tt][Rr][Aa][Ii][Ll][Ii][Nn][Gg] {SQL_NEW_KEYWORD(SQL_TOKEN_TRAILING); return SQL_TOKEN_TRAILING; }
+[Tt][Rr][Aa][Nn][Ss][Ll][Aa][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_TRANSLATE); return SQL_TOKEN_TRANSLATE; }
+[Tt][Rr][Ii][Mm] {SQL_NEW_KEYWORD(SQL_TOKEN_TRIM); return SQL_TOKEN_TRIM; }
+[Tt][Rr][Uu][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_TRUE); return SQL_TOKEN_TRUE; }
+[Tt][Ss] {SQL_NEW_KEYWORD(SQL_TOKEN_TS); return SQL_TOKEN_TS; }
+
+[Uu][Nn][Ii][Oo][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_UNION); return SQL_TOKEN_UNION; }
+[Uu][Nn][Ii][Qq][Uu][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_UNIQUE); return SQL_TOKEN_UNIQUE; }
+[Uu][Nn][Kk][Nn][Oo][Ww][Nn] {SQL_NEW_KEYWORD(SQL_TOKEN_UNKNOWN); return SQL_TOKEN_UNKNOWN; }
+[Uu][Pp][Pp][Ee][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_UPPER); return SQL_TOKEN_UPPER; }
+[Uu][Pp][Dd][Aa][Tt][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_UPDATE); return SQL_TOKEN_UPDATE; }
+[Uu][Ss][Aa][Gg][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_USAGE); return SQL_TOKEN_USAGE; }
+[Uu][Ss][Ee][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_USER); return SQL_TOKEN_USER; }
+[Uu][Ss][Ii][Nn][Gg] {SQL_NEW_KEYWORD(SQL_TOKEN_USING); return SQL_TOKEN_USING; }
+
+[Vv][Aa][Ll][Uu][Ee][Ss] {SQL_NEW_KEYWORD(SQL_TOKEN_VALUES); return SQL_TOKEN_VALUES; }
+[Vv][Ii][Ee][Ww] {SQL_NEW_KEYWORD(SQL_TOKEN_VIEW); return SQL_TOKEN_VIEW; }
+
+[Ww][Hh][Ee][Rr][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_WHERE); return SQL_TOKEN_WHERE; }
+[Ww][Ii][Tt][Hh] {SQL_NEW_KEYWORD(SQL_TOKEN_WITH); return SQL_TOKEN_WITH; }
+[Ww][Oo][Rr][Kk] {SQL_NEW_KEYWORD(SQL_TOKEN_WORK); return SQL_TOKEN_WORK; }
+
+[Yy][Ee][Aa][Rr] {SQL_NEW_KEYWORD(SQL_TOKEN_YEAR); return SQL_TOKEN_YEAR; }
+
+[Zz][Oo][Nn][Ee] {SQL_NEW_KEYWORD(SQL_TOKEN_ZONE); return SQL_TOKEN_ZONE; }
+
+"<" { SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_LESS);return LESS;}
+">" { SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_GREAT);return GREAT;}
+"=" { SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_EQUAL);return EQUAL;}
+"<=" { SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_LESSEQ);return LESSEQ;}
+">=" { SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_GREATEQ);return GREATEQ;}
+"<>" { SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_NOTEQUAL);return NOTEQUAL;}
+"!=" { SQL_NEW_NODE(String::CreateFromAscii(SQLyytext), SQL_NODE_NOTEQUAL);return NOTEQUAL;}
+
+
+[-+*/:(),.;?{}] { return SQLyytext[0]; }
+
+<SQL>[A-Za-z][A-Za-z0-9_]* {return gatherName( SQLyytext);}
+
+<SQL>([0-9]+) |
+<SQL>([0-9]+"."[0-9]*) |
+<SQL>("."[0-9]*) {SQL_NEW_INTNUM; return SQL_TOKEN_INTNUM;}
+
+<SQL>[0-9]+[eE][+-]?[0-9]+ |
+<SQL>[0-9]+"."[0-9]*[eE][+-]?[0-9]+ |
+<SQL>"."[0-9]*[eE][+-]?[0-9]+ {SQL_NEW_APPROXNUM; return SQL_TOKEN_APPROXNUM; }
+
+<PREDICATE_GER,PREDICATE_ENG,DATE>[A-Za-z][A-Za-z0-9_%.,*?]* {return gatherNamePre(SQLyytext);}
+
+<PREDICATE_GER,PREDICATE_ENG>([0-9]+) {SQL_NEW_INTNUM; return SQL_TOKEN_INTNUM;}
+<PREDICATE_ENG>([0-9]{1,3}(","[0-9]{3})+) {SQL_NEW_INTNUM; return SQL_TOKEN_INTNUM;}
+<PREDICATE_GER>([0-9]{1,3}("."[0-9]{3})+) {SQL_NEW_INTNUM; return SQL_TOKEN_INTNUM;}
+
+<PREDICATE_ENG>([0-9]+"."[0-9]+) |
+<PREDICATE_ENG>([0-9]{1,3}(","[0-9]{3})+"."[0-9]+) |
+<PREDICATE_ENG>("."[0-9]+) {SQL_NEW_APPROXNUM; return SQL_TOKEN_APPROXNUM; }
+<PREDICATE_ENG>[0-9]+[eE][+-]?[0-9]+ |
+<PREDICATE_ENG>[0-9]+"."[0-9]*[eE][+-]?[0-9]+ |
+<PREDICATE_ENG>"."[0-9]*[eE][+-]?[0-9]+ {SQL_NEW_APPROXNUM; return SQL_TOKEN_APPROXNUM; }
+
+<PREDICATE_GER>([0-9]+","[0-9]+) |
+<PREDICATE_GER>([0-9]{1,3}("."[0-9]{3})+","[0-9]+) |
+<PREDICATE_GER>(","[0-9]+) {SQL_NEW_APPROXNUM; return SQL_TOKEN_APPROXNUM; }
+<PREDICATE_GER>[0-9]+[eE][+-]?[0-9]+ |
+<PREDICATE_GER>[0-9]+","[0-9]*[eE][+-]?[0-9]+ |
+<PREDICATE_GER>","[0-9]*[eE][+-]?[0-9]+ {SQL_NEW_APPROXNUM; return SQL_TOKEN_APPROXNUM; }
+
+<PREDICATE_GER,PREDICATE_ENG>[0-9.,][A-Za-z0-9_.,%]* {return gatherNamePre(SQLyytext);}
+
+<SQL>\" { return gatherString('\"',0); }
+<SQL>` { return gatherString('`' ,0); }
+
+<PREDICATE_GER,PREDICATE_ENG,DATE>"[" { return gatherString(']' ,0);}
+
+\' { return gatherString('\'',1); }
+
+<PREDICATE_GER,PREDICATE_ENG,DATE># { return gatherString('#' ,2); }
+
+<DATE>[0-9]{1,4}[^ ]*[0-9] |
+<DATE>[0-9]{1,4}[^ ]*[0-9][ ][0-9]{1,4}[^ ]*[0-9] { SQL_NEW_DATE; return SQL_TOKEN_ACCESS_DATE;}
+
+<STRING>["-""+""*""/"":""("")"",""."";""?""{""}"] { return SQLyytext[0]; } /* */
+<STRING>"[" { return gatherString(']' ,0); }
+<STRING>[^ ':[]* { return gatherNamePre(SQLyytext); }
+
+\n {}
+
+[ \t\r]+ ;
+
+"--".*$ ;
+
+. {YY_FATAL_ERROR("Invalid symbol"); return SQL_TOKEN_INVALIDSYMBOL;}
+
+%%
+
+/*
+ * Read SQL string literal
+ * Valid strings:
+ * '' 'a string' 'quote '' within string'
+ * "" "a string" "quote "" within string"
+ * nTyp == 0 -> SQL_NODE_NAME
+ * nTyp == 1 -> SQL_NODE_STRING
+ * nTyp == 2 -> SQL_NODE_ACCESS_DATE
+ */
+int gatherString( int delim, int nTyp)
+{
+ int ch;
+ static sal_Int32 BUFFERSIZE = 256;
+ static char* Buffer = new char[BUFFERSIZE];
+
+ char *s = Buffer;
+ int nPos = 0;
+
+ while ((ch = yyinput()) != EOF)
+ {
+ if (ch == delim)
+ {
+ if ((ch = yyinput()) != delim)
+ {
+ if (ch != EOF)
+ unput(ch);
+
+ *s = '\0';
+
+ switch(nTyp)
+ {
+ case 0:
+ SQL_NEW_NODE(String(Buffer,RTL_TEXTENCODING_UTF8), SQL_NODE_NAME);
+ return SQL_TOKEN_NAME;
+ case 1:
+ SQL_NEW_NODE(String(Buffer,RTL_TEXTENCODING_UTF8), SQL_NODE_STRING);
+ return SQL_TOKEN_STRING;
+ case 2:
+ SQL_NEW_NODE(String(Buffer,RTL_TEXTENCODING_UTF8), SQL_NODE_ACCESS_DATE);
+ return SQL_TOKEN_ACCESS_DATE;
+ }
+ }
+ else
+ {
+ *s++ = ch;
+ if (++nPos == BUFFERSIZE)
+ {
+ ByteString aBuf(Buffer);
+ delete Buffer;
+ BUFFERSIZE *=2;
+ Buffer = new char[BUFFERSIZE];
+ for(xub_StrLen i=0;i<aBuf.Len();++i,++Buffer)
+ *Buffer = aBuf.GetChar(i);
+ s = &Buffer[nPos];
+ }
+ }
+
+ }
+ else if (ch == '\r' || ch == '\n')
+ break;
+ else
+ {
+ *s++ = ch;
+ if (++nPos == BUFFERSIZE)
+ {
+ ByteString aBuf(Buffer);
+ delete Buffer;
+ BUFFERSIZE *=2;
+ Buffer = new char[BUFFERSIZE];
+ for(xub_StrLen i=0;i<aBuf.Len();++i,++Buffer)
+ *Buffer = aBuf.GetChar(i);
+ s = &Buffer[nPos];
+ }
+ }
+ }
+ *s = '\0';
+ YY_FATAL_ERROR("Unterminated name string");
+ return SQL_TOKEN_INVALIDSYMBOL;
+}
+
+/*
+ * Read SQL Name literal
+ * Valid Names or internatioanl keywords:
+ * As we have international keywords, we test first on them
+ */
+int gatherName(const char* text)
+{
+ OSL_ENSHURE(xxx_pGLOBAL_SQLSCAN,"You forgot to set the scanner!");
+ int nToken = xxx_pGLOBAL_SQLSCAN->getInternationalTokenID(text);
+ switch (nToken)
+ {
+ case SQL_TOKEN_LIKE:
+ case SQL_TOKEN_NOT:
+ case SQL_TOKEN_NULL:
+ case SQL_TOKEN_TRUE:
+ case SQL_TOKEN_FALSE:
+ case SQL_TOKEN_IS:
+ case SQL_TOKEN_BETWEEN:
+ case SQL_TOKEN_OR:
+ case SQL_TOKEN_AND:
+ case SQL_TOKEN_COUNT:
+ case SQL_TOKEN_AVG:
+ case SQL_TOKEN_MAX:
+ case SQL_TOKEN_MIN:
+ case SQL_TOKEN_SUM:
+ SQL_NEW_KEYWORD(nToken);
+ return nToken;
+ default:
+ SQL_NEW_NODE(String::CreateFromAscii(text), SQL_NODE_NAME);
+ return SQL_TOKEN_NAME;
+ }
+}
+/**
+ Read SQL Name literal for predicate check
+ Valid Names or internatioanl keywords:
+ As we have international keywords, we test first on them
+*/
+int gatherNamePre(const char* text)
+{
+ OSL_ENSHURE(xxx_pGLOBAL_SQLSCAN,"You forgot to set the scanner!");
+ int nToken = xxx_pGLOBAL_SQLSCAN->getInternationalTokenID(text);
+ switch (nToken)
+ {
+ case SQL_TOKEN_LIKE:
+ case SQL_TOKEN_NOT:
+ case SQL_TOKEN_NULL:
+ case SQL_TOKEN_TRUE:
+ case SQL_TOKEN_FALSE:
+ case SQL_TOKEN_IS:
+ case SQL_TOKEN_BETWEEN:
+ case SQL_TOKEN_OR:
+ case SQL_TOKEN_AND:
+ case SQL_TOKEN_COUNT:
+ case SQL_TOKEN_AVG:
+ case SQL_TOKEN_MAX:
+ case SQL_TOKEN_MIN:
+ case SQL_TOKEN_SUM:
+ SQL_NEW_KEYWORD(nToken);
+ return nToken;
+ default:
+ // we need a special handling for parameter
+ if (yy_hold_char == ':')
+ {
+ SQL_NEW_NODE(String::CreateFromAscii(text), SQL_NODE_NAME);
+ return SQL_TOKEN_NAME;
+ }
+ else
+ {
+ SQL_NEW_NODE(String::CreateFromAscii(text), SQL_NODE_STRING);
+ return SQL_TOKEN_STRING;
+ }
+ }
+}
+
+using namespace connectivity;
+
+static sal_uInt32 Intl_TokenID[] =
+{
+ SQL_TOKEN_LIKE, SQL_TOKEN_NOT, SQL_TOKEN_NULL, SQL_TOKEN_TRUE,
+ SQL_TOKEN_FALSE, SQL_TOKEN_IS, SQL_TOKEN_BETWEEN, SQL_TOKEN_OR,
+ SQL_TOKEN_AND, SQL_TOKEN_AVG, SQL_TOKEN_COUNT, SQL_TOKEN_MAX,
+ SQL_TOKEN_MIN, SQL_TOKEN_SUM
+};
+
+DBG_NAME(OSQLScanner);
+
+//------------------------------------------------------------------------------
+OSQLScanner::OSQLScanner()
+ : m_nCurrentPos(0)
+ , m_bInternational(sal_False)
+ , m_pContext(NULL)
+ , m_nRule(0) // 0 is INITIAL
+{
+ DBG_CTOR(OSQLScanner,NULL);
+}
+
+//------------------------------------------------------------------------------
+OSQLScanner::~OSQLScanner()
+{
+ DBG_DTOR(OSQLScanner,NULL);
+}
+
+//------------------------------------------------------------------------------
+void OSQLScanner::SQLyyerror(char *fmt)
+{
+ DBG_ASSERT(m_pContext, "OSQLScanner::SQLyyerror: No Context set");
+ m_sErrorMessage = m_pContext->getErrorMessage(OParseContext::ERROR_GENERAL);
+ if (m_nCurrentPos < m_sStatement.Len())
+ {
+ m_sErrorMessage.AppendAscii(": ");
+ m_sErrorMessage += m_pContext->getErrorMessage(OParseContext::ERROR_GENERAL_HINT);
+ m_sErrorMessage.SearchAndReplaceAscii("#",String::CreateFromAscii(SQLyytext));
+ }
+}
+
+//------------------------------------------------------------------------------
+void OSQLScanner::prepareScan(const String & rNewStatement, OParseContext* pContext, sal_Bool bInternational)
+{
+ DBG_CHKTHIS(OSQLScanner,NULL);
+
+ BEGIN(m_nRule);
+
+ m_sErrorMessage.Erase();
+ m_sStatement = ByteString(rNewStatement, RTL_TEXTENCODING_UTF8);
+ m_nCurrentPos = 0;
+ m_bInternational = bInternational;
+ m_pContext = pContext;
+}
+
+//------------------------------------------------------------------------------
+int OSQLScanner::SQLyygetc(void)
+{
+ return (m_nCurrentPos >= m_sStatement.Len()) ? -1 : m_sStatement.GetChar(m_nCurrentPos++);
+}
+
+//------------------------------------------------------------------------------
+int OSQLScanner::getInternationalTokenID(const char* sToken) const
+{
+ DBG_ASSERT(m_pContext, "OSQLScanner::getInternationalTokenID: No Context set");
+ return (m_bInternational) ? m_pContext->getIntlKeyCode(ByteString(sToken, RTL_TEXTENCODING_ASCII_US)) : 0;
+}
+// -------------------------------------------------------------------------
+int OSQLScanner::GetCurrentRule() const { return m_nRule; }
+int OSQLScanner::GetGERRule() const { return PREDICATE_GER; }
+int OSQLScanner::GetENGRule() const { return PREDICATE_ENG; }
+int OSQLScanner::GetSQLRule() const { return SQL; }
+int OSQLScanner::GetDATERule() const { return DATE; }
+int OSQLScanner::GetSTRINGRule() const { return STRING; }
+// -------------------------------------------------------------------------
+void OSQLScanner::setScanner(sal_Bool _bNull)
+{
+ xxx_pGLOBAL_SQLSCAN = _bNull ? NULL : this;
+}
+// -------------------------------------------------------------------------
+int OSQLScanner::SQLlex()
+{
+ return SQLyylex();
+}
+/*------------------------------------------------------------------------
+
+ $Log: not supported by cvs2svn $
+ Revision 1.2 2000/08/01 14:26:02 oj
+ modified
+
+ Revision 1.1 2000/07/25 10:39:47 oj
+ new revision
+
+ Revision 1.0 21.07.2000 10:54:08 oj
+------------------------------------------------------------------------*/
+
diff --git a/connectivity/source/parse/sqliterator.cxx b/connectivity/source/parse/sqliterator.cxx
new file mode 100644
index 000000000000..88e98fa418a7
--- /dev/null
+++ b/connectivity/source/parse/sqliterator.cxx
@@ -0,0 +1,1583 @@
+/*************************************************************************
+ *
+ * $RCSfile: sqliterator.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:14:28 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
+#include "connectivity/sqliterator.hxx"
+#endif
+
+#ifndef _CONNECTIVITY_SQLPARSE_HXX
+#include <connectivity/sqlparse.hxx>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
+#include <com/sun/star/sdbc/DataType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
+#include <com/sun/star/sdbc/XRow.hpp>
+#endif
+#ifdef SQL_TEST_PARSETREEITERATOR
+#include <iostream.h>
+#endif
+#ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
+#include "connectivity/PColumn.hxx"
+#endif
+#ifndef _CONNECTIVITY_SDBCX_COLLECTION_HXX_
+#include "connectivity/sdbcx/VCollection.hxx"
+#endif
+#ifndef _CONNECTIVITY_PROPERTYIDS_HXX_
+#include "propertyids.hxx"
+#endif
+
+using namespace connectivity;
+using namespace connectivity::parse;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+
+DBG_NAME(OSQLParseTreeIterator);
+static String aEmptyString;
+
+class OPrivateColumns : public sdbcx::OCollection
+{
+ OSQLColumns m_aColumns;
+protected:
+ virtual Reference< XNamed > createObject(const ::rtl::OUString& _rName);
+ virtual void impl_refresh() throw(RuntimeException) {}
+ virtual Reference< XPropertySet > createEmptyObject()
+ {
+ return NULL;
+ }
+public:
+ OPrivateColumns(const OSQLColumns& _rColumns,
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector
+ ) : sdbcx::OCollection(_rParent,sal_True,_rMutex,_rVector)
+ ,m_aColumns(_rColumns)
+ {}
+ ~OPrivateColumns()
+ {
+ disposing();
+ }
+};
+// -------------------------------------------------------------------------
+Reference< XNamed > OPrivateColumns::createObject(const ::rtl::OUString& _rName)
+{
+ return Reference< XNamed >(*find(m_aColumns.begin(),m_aColumns.end(),_rName,isCaseSensitive()),UNO_QUERY);
+}
+// -------------------------------------------------------------------------
+class OPrivateTables : public sdbcx::OCollection
+{
+ OSQLTables m_aTables;
+protected:
+ virtual Reference< XNamed > createObject(const ::rtl::OUString& _rName);
+ virtual void impl_refresh() throw(RuntimeException) {}
+ virtual Reference< XPropertySet > createEmptyObject()
+ {
+ return NULL;
+ }
+public:
+ OPrivateTables(const OSQLTables& _rColumns,
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector
+ ) : sdbcx::OCollection(_rParent,sal_True,_rMutex,_rVector)
+ ,m_aTables(_rColumns)
+ {}
+};
+// -------------------------------------------------------------------------
+Reference< XNamed > OPrivateTables::createObject(const ::rtl::OUString& _rName)
+{
+ return Reference< XNamed >(m_aTables.find(_rName)->second,UNO_QUERY);
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseTreeIterator::OSQLParseTreeIterator()
+ : m_pParseTree(NULL)
+ , m_xTables(NULL)
+ , m_xDatabaseMetaData(NULL)
+{
+ DBG_CTOR(OSQLParseTreeIterator,NULL);
+ m_aSelectColumns = new OSQLColumns();
+}
+//-----------------------------------------------------------------------------
+OSQLParseTreeIterator::OSQLParseTreeIterator(const Reference< XNameAccess>& _xTables ,
+ const Reference< XDatabaseMetaData>& _xDatabaseMetaData,
+ const OSQLParseNode* pRoot)
+ : m_xTables(_xTables)
+ , m_xDatabaseMetaData(_xDatabaseMetaData)
+ , m_aTables(_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers())
+ , m_aCaseEqual(_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers())
+{
+ DBG_CTOR(OSQLParseTreeIterator,NULL);
+ m_aSelectColumns = new OSQLColumns();// must be done because we need an empty column at zero
+ setParseTree(pRoot);
+}
+//-----------------------------------------------------------------------------
+OSQLParseTreeIterator::OSQLParseTreeIterator(const OSQLParseTreeIterator & rIter)
+ :m_xTables(NULL)
+ ,m_pParseTree(NULL)
+ , m_xDatabaseMetaData(NULL)
+{
+ DBG_CTOR(OSQLParseTreeIterator,NULL);
+
+ DBG_ERROR("OSQLParseTreeIterator: Copy-Konstruktor nicht implementiert!");
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseTreeIterator::~OSQLParseTreeIterator()
+{
+ DBG_DTOR(OSQLParseTreeIterator,NULL);
+ m_aTables.clear();
+}
+// -------------------------------------------------------------------------
+Reference< XNameAccess > OSQLParseTreeIterator::getSelectAsNameAccess(::cppu::OWeakObject& _rParent,::osl::Mutex& _rMutex) const
+{
+ ::std::vector< ::rtl::OUString> aNames;
+ for(OSQLColumns::const_iterator aIter = m_aSelectColumns->begin(); aIter != m_aSelectColumns->end();++aIter)
+ aNames.push_back(getString((*aIter)->getFastPropertyValue(PROPERTY_ID_NAME)));
+ OPrivateColumns* pCols = new OPrivateColumns(*m_aSelectColumns,_rParent,_rMutex,aNames);
+ return pCols;
+}
+// -------------------------------------------------------------------------
+Reference< XNameAccess > OSQLParseTreeIterator::getTablesAsNameAccess(::cppu::OWeakObject& _rParent,::osl::Mutex& _rMutex) const
+{
+ ::std::vector< ::rtl::OUString> aNames;
+ for(OSQLTables::const_iterator aIter = m_aTables.begin(); aIter != m_aTables.end();++aIter)
+ {
+ Reference<XNamed> xName(aIter->second,UNO_QUERY);
+ aNames.push_back(xName->getName());
+ }
+ OPrivateTables* pTabs = new OPrivateTables(m_aTables,_rParent,_rMutex,aNames);
+ return pTabs;
+}
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setParseTree(const OSQLParseNode * pNewParseTree)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // alle Eingaben zur"uck setzen
+ // aIteratorStatus.Clear();
+// for(ULONG i=0; i< m_aTables.count();i++)
+// delete m_aTables.getObject(i);
+ m_aTables.clear();
+
+ m_aSelectColumns->clear();
+
+ m_pParseTree = pNewParseTree;
+ if (!m_pParseTree)
+ {
+ m_eStatementType = SQL_STATEMENT_UNKNOWN;
+ return;
+ }
+
+ // falls m_pParseTree aber keine Connection, dann Fehler
+ if(!m_xTables.is())
+ {
+ //aIteratorStatus.setInvalidStatement();
+ CallError(RET_BREAK);
+ return;
+ }
+
+ // m_aTables.setCaseSensitive(TablesAreSensitive());
+
+
+ // Statement-Typ ermitteln ...
+ if (SQL_ISRULE(m_pParseTree,select_statement) || SQL_ISRULE(m_pParseTree,union_statement) )
+ {
+ m_eStatementType = SQL_STATEMENT_SELECT;
+ }
+ else if (SQL_ISRULE(m_pParseTree,insert_statement))
+ {
+ m_eStatementType = SQL_STATEMENT_INSERT;
+ }
+ else if (SQL_ISRULE(m_pParseTree,update_statement_positioned))
+ {
+ m_eStatementType = SQL_STATEMENT_UPDATE;
+ }
+ else if (SQL_ISRULE(m_pParseTree,update_statement_searched))
+ {
+ m_eStatementType = SQL_STATEMENT_UPDATE;
+ }
+ else if (SQL_ISRULE(m_pParseTree,delete_statement_positioned))
+ {
+ m_eStatementType = SQL_STATEMENT_DELETE;
+ }
+ else if (SQL_ISRULE(m_pParseTree,delete_statement_searched))
+ {
+ m_eStatementType = SQL_STATEMENT_DELETE;
+ }
+ else if (m_pParseTree->count() == 3 && SQL_ISRULE(m_pParseTree->getChild(1),odbc_call_spec))
+ {
+ m_eStatementType = SQL_STATEMENT_ODBC_CALL;
+ }
+ else
+ {
+ m_eStatementType = SQL_STATEMENT_UNKNOWN;
+ //aIteratorStatus.setInvalidStatement();
+ CallError(RET_BREAK);
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseOneTableName(const OSQLParseNode * pTableName, const String & rTableRange)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ DBG_ASSERT(pTableName != NULL,"OSQLParseTreeIterator::traverseOneTableName: pTableName == NULL");
+
+ String aTableName;
+ String aTableRange(rTableRange);
+
+ // Tabellenname abholen
+ pTableName->parseNodeToStr(aTableName,m_xDatabaseMetaData,NULL,FALSE,FALSE);
+ // Wenn keine Range Variable angegeben, dann den Tabellennamen verwenden.
+ if (!aTableRange.Len())
+ aTableRange = aTableName;
+
+ if(aTableName.Len())
+ {
+ try
+ {
+ if(!m_xTables->hasByName(aTableName)) // name not in XNameAccess
+ {
+ const ::rtl::OUString sAll = ::rtl::OUString::createFromAscii("%");
+ Sequence< ::rtl::OUString > aSeq;
+ Reference< XResultSet> xRes = m_xDatabaseMetaData->getTables(Any(),sAll,aTableName,aSeq);
+ if(xRes.is() && xRes->next())
+ {
+ ::rtl::OUString sCatalog, sSchema, sName;
+ Reference< XRow > xCurrentRow(xRes, UNO_QUERY);
+ sCatalog = xCurrentRow->getString(1);
+ sSchema = xCurrentRow->getString(2);
+ sName = xCurrentRow->getString(3);
+
+ if(sCatalog.getLength())
+ {
+ aTableName = sCatalog;
+ aTableName += m_xDatabaseMetaData->getCatalogSeparator().getStr();
+ }
+ if(sSchema.getLength())
+ {
+ aTableName += sSchema.getStr();
+ aTableName += ::rtl::OUString::createFromAscii(".").getStr();
+ }
+ aTableName += sName.getStr();
+ }
+ }
+ Any aTable(m_xTables->getByName(aTableName));
+ OSQLTable xSet;
+
+ if(aTable >>= xSet)
+ m_aTables[aTableRange] = xSet;
+ }catch(...)
+ {
+ if (CallError(RET_CONTINUE))
+ m_aTables[aTableRange] = NULL; // ich soll den Fehler ignorieren
+ }
+
+ }
+ else
+ CallError(RET_BREAK,rTableRange);
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode * OSQLParseTreeIterator::getQualified_join(OSQLParseNode *pTableRef,String& aTableRange)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ aTableRange.Erase();
+
+ OSQLParseNode *pNode = getTableRef(pTableRef->getChild(0),aTableRange);
+ if(pNode)
+ traverseOneTableName(pNode,aTableRange);
+ ULONG nPos = 4;
+ if(SQL_ISRULE(pTableRef,cross_union) || pTableRef->getChild(1)->getTokenID() != SQL_TOKEN_NATURAL)
+ nPos = 3;
+
+
+ pNode = getTableRef(pTableRef->getChild(nPos),aTableRange);
+ if(pNode)
+ traverseOneTableName(pNode,aTableRange);
+ return pNode;
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode * OSQLParseTreeIterator::getTableRef(OSQLParseNode *pTableRef,String& aTableRange)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ OSQLParseNode *pTableName = pTableRef;
+ if (pTableName->count() == 4 )
+ {
+ if(SQL_ISPUNCTUATION(pTableName->getChild(0),"{"))
+ { // { OJ joined_table }
+ getQualified_join(pTableName->getChild(2),aTableRange);
+ pTableName = NULL;
+ }
+ else
+ {
+ // Tabellennamen gefunden
+ if(!SQL_ISRULE(pTableName,table_name))
+ pTableName = pTableRef->getChild(0);
+ aTableRange.Erase();
+ if(pTableRef->count() == 4)
+ aTableRange = pTableRef->getChild(2)->getTokenValue(); // Tabellenrange an Pos 2
+ }
+ }
+ else if(SQL_ISRULE(pTableName,qualified_join) || SQL_ISRULE(pTableName,cross_union))
+ {
+ getQualified_join(pTableRef,aTableRange);
+ pTableName = NULL;
+ }
+ else if (SQL_ISRULE(pTableName,joined_table))
+ {
+ // '(' qualified_join ')'
+ getQualified_join(pTableName->getChild(1),aTableRange);
+ pTableName = NULL;
+ }
+ else if(pTableRef->count() == 6)
+ {
+ // '(' joined_table ')' as range_variable op_column_commalist
+ if(SQL_ISRULE(pTableRef->getChild(1),qualified_join) || SQL_ISRULE(pTableRef->getChild(1),cross_union))
+ getQualified_join(pTableRef->getChild(1),aTableRange);
+ else if(SQL_ISRULE(pTableRef->getChild(1),select_statement)) // Unterabfrage
+ getSelect_statement(pTableRef->getChild(1));
+ else if(pTableRef->getChild(1)->count() == 4)
+ // pTableRef->getChild(1) ->> non_join_query_exp
+ getSelect_statement(pTableRef->getChild(0)); // query_exp SQL_TOKEN_UNION all query_term
+ else
+ {// nyi: tiefere Verschachtelung m"oglch
+ CallError(4);
+ }
+ }
+ return pTableName;
+}
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::getSelect_statement(OSQLParseNode *pSelect)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ if(SQL_ISRULE(pSelect,union_statement))
+ {
+ getSelect_statement(pSelect->getChild(0));
+ //getSelect_statement(pSelect->getChild(3));
+ return;
+ }
+ OSQLParseNode * pTableRefCommalist = pSelect->getChild(3)->getChild(0)->getChild(1);
+
+ DBG_ASSERT(pTableRefCommalist != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pTableRefCommalist,table_ref_commalist),"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ OSQLParseNode * pTableName = NULL;
+ String aTableRange;
+ for (ULONG i = 0; i < pTableRefCommalist->count(); i++)
+ { // from clause durchlaufen
+ aTableRange.Erase();
+
+ if (SQL_ISRULE(pTableRefCommalist->getChild(i),table_name))
+ {
+ pTableName = pTableRefCommalist->getChild(i);
+ traverseOneTableName(pTableName,aTableRange);// Keine Range Variable
+ }
+ else if (SQL_ISRULE(pTableRefCommalist->getChild(i),table_ref))
+ {
+ // Tabellenreferenz kann aus Tabellennamen, Tabellennamen (+),'('joined_table')'(+) bestehen
+ pTableName = pTableRefCommalist->getChild(i)->getChild(0);
+ if (SQL_ISRULE(pTableName,table_name))
+ { // Tabellennamen gefunden
+ if(pTableRefCommalist->getChild(i)->count() == 4) // Tabellenrange an Pos 2
+ aTableRange = pTableRefCommalist->getChild(i)->getChild(2)->getTokenValue();
+ traverseOneTableName(pTableName,aTableRange);
+ }
+ else if(SQL_ISPUNCTUATION(pTableName,"{"))
+ getQualified_join(pTableRefCommalist->getChild(i)->getChild(2),aTableRange);
+ else // '(' joined_table ')' as range_variable op_column_commalist
+ getTableRef(pTableRefCommalist->getChild(i),aTableRange);
+ }
+ else if (SQL_ISRULE(pTableRefCommalist->getChild(i),qualified_join) || SQL_ISRULE(pTableRefCommalist->getChild(i),cross_union) )
+ {
+ // qualified_join oder cross_union vorhanden
+ getQualified_join(pTableRefCommalist->getChild(i),aTableRange);
+ }
+ else if (SQL_ISRULE(pTableRefCommalist->getChild(i),joined_table))
+ {
+ // '(' qualified_join ')'
+ getQualified_join(pTableRefCommalist->getChild(i)->getChild(1),aTableRange);
+ }
+ else
+ {
+ CallError(3,aTableRange);
+ }
+
+ // if (! aIteratorStatus.IsSuccessful()) break;
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseTableNames()
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // aIteratorStatus.Clear();
+
+ if (m_pParseTree == NULL) {
+ //aIteratorStatus.setInvalidStatement();
+ CallError(3);
+ return;
+ }
+
+ OSQLParseNode * pTableName = NULL;
+ String aTableRange;
+
+ // pTableName auf den (einzigen) Tabellennamen im Statement setzen.
+ // Je nach Statement (SELECT, INSERT, UPDATE, DELETE) an anderer Position.
+ // Bei Select koennen mehrere Tabellennamen auftreten, bei den uebrigen Statements
+ // ist ohnehin immer nur einer moeglich.
+
+ if (m_eStatementType == SQL_STATEMENT_SELECT)
+ {
+ OSQLParseNode *pTmp = (OSQLParseNode *)m_pParseTree;
+ getSelect_statement(pTmp);
+ }
+ else if (m_eStatementType == SQL_STATEMENT_INSERT)
+ {
+ pTableName = m_pParseTree->getChild(2);
+ traverseOneTableName(pTableName,aTableRange);
+ }
+ else if (m_eStatementType == SQL_STATEMENT_UPDATE)
+ {
+ pTableName = m_pParseTree->getChild(1);
+ traverseOneTableName(pTableName,aTableRange);
+ }
+ else if (m_eStatementType == SQL_STATEMENT_DELETE)
+ {
+ pTableName = m_pParseTree->getChild(2);
+ traverseOneTableName(pTableName,aTableRange);
+ } else
+ {
+ CallError(5,aTableRange);
+ }
+}
+//-----------------------------------------------------------------------------
+String OSQLParseTreeIterator::getColumnAlias(const OSQLParseNode* pDerivedColumn) const
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ String aColumnAlias;
+ if(pDerivedColumn->getChild(1)->count() == 2)
+ aColumnAlias = pDerivedColumn->getChild(1)->getChild(1)->getTokenValue();
+ else if(!pDerivedColumn->getChild(1)->isRule())
+ aColumnAlias = pDerivedColumn->getChild(1)->getTokenValue();
+ return aColumnAlias;
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::getColumnRange(const OSQLParseNode* pColumnRef,String &rColumnName,String &rTableRange) const
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ rColumnName.Erase();
+ rTableRange.Erase();
+ if(SQL_ISRULE(pColumnRef,column_ref))// ab hier ist es sicher eine Columnref
+ {
+ if(pColumnRef->count() > 1)
+ {
+ for(INT32 i=0;i<((INT32)pColumnRef->count())-2;i++) // mu"s signed sein, falls count == 1
+ pColumnRef->getChild(i)->parseNodeToStr(rTableRange,m_xDatabaseMetaData,NULL,FALSE,FALSE);
+ // Spaltenname
+ rColumnName = pColumnRef->getChild(pColumnRef->count()-1)->getChild(0)->getTokenValue();
+ }
+ else
+ rColumnName = pColumnRef->getChild(0)->getTokenValue();
+ }
+ else if(SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec))
+ { // Funktion
+ pColumnRef->parseNodeToStr(rColumnName,m_xDatabaseMetaData);
+ }
+ else if(pColumnRef->getNodeType() == SQL_NODE_NAME)
+ rColumnName = pColumnRef->getTokenValue();
+}
+
+//-----------------------------------------------------------------------------
+BOOL OSQLParseTreeIterator::getColumnTableRange(const OSQLParseNode* pNode, String &rTableRange) const
+{
+ // Ermitteln ob alle Spalten zu einer Tabelle gehoeren
+ if (SQL_ISRULE(pNode,column_ref))
+ {
+ String aColName, aTableRange;
+ getColumnRange(pNode, aColName, aTableRange);
+ if (!aTableRange.Len()) // keinen gefunden
+ {
+ // dann die Spalte in den Tabellen suchen
+ for (ConstOSQLTablesIterator aIter = m_aTables.begin(); aIter != m_aTables.end(); ++aIter)
+ {
+ if (aIter->second.is())
+ {
+ try
+ {
+ Reference< XNameAccess > xColumns = aIter->second->getColumns();
+ Any aColumn(xColumns->getByName(aColName));
+ Reference< XFastPropertySet > xColumn;
+
+ if (aColumn >>= xColumn)
+ {
+ aTableRange = aIter->first;
+ break;
+ }
+ }
+ catch(...)
+ {
+ }
+ }
+ }
+ if (!aTableRange.Len())
+ return FALSE;
+ }
+
+
+ if (!rTableRange.Len())
+ rTableRange = aTableRange;
+ else if (rTableRange != aTableRange)
+ return FALSE;
+ }
+ else
+ {
+ for (UINT32 i = 0, ncount = pNode->count(); i < ncount; i++)
+ {
+ if (!getColumnTableRange(pNode->getChild(i), rTableRange))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseSelectColumnNames(const OSQLParseNode* pSelectNode)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // aIteratorStatus.Clear();
+
+ if (!pSelectNode || m_eStatementType != SQL_STATEMENT_SELECT || !m_aTables.size())
+ {
+ //aIteratorStatus.setInvalidStatement();
+ CallError(3);
+ return;
+ }
+
+ if(SQL_ISRULE(pSelectNode,union_statement))
+ {
+ traverseSelectColumnNames(pSelectNode->getChild(0));
+// traverseSelectColumnNames(pSelectNode->getChild(3));
+ return;
+ }
+
+ // nyi: mehr Pruefung auf korrekte Struktur!
+ if (pSelectNode->getChild(2)->isRule() && SQL_ISPUNCTUATION(pSelectNode->getChild(2)->getChild(0),"*"))
+ {
+ // SELECT * ...
+ setSelectColumnName(String::CreateFromAscii("*"), aEmptyString,aEmptyString);
+ }
+ else if (SQL_ISRULE(pSelectNode->getChild(2),scalar_exp_commalist))
+ {
+ // SELECT column(,column) oder SELECT COUNT(*) ...
+ OSQLParseNode * pSelection = pSelectNode->getChild(2);
+
+ for (ULONG i = 0; i < pSelection->count(); i++)
+ {
+ OSQLParseNode *pColumnRef = pSelection->getChild(i);
+
+ if (SQL_ISRULE(pColumnRef,select_sublist))
+ {
+ // alle Spalten der Tabelle
+ String aTableRange;
+ pColumnRef->getChild(0)->parseNodeToStr(aTableRange,m_xDatabaseMetaData,NULL,FALSE,FALSE);
+ setSelectColumnName(String::CreateFromAscii("*"), aEmptyString,aTableRange);
+ continue;
+ }else if (SQL_ISRULE(pColumnRef,derived_column))
+ {
+ String aColumnAlias(getColumnAlias(pColumnRef)); // kann leer sein
+ String aColumnName;
+ String aTableRange;
+ BOOL bFkt(FALSE);
+ pColumnRef = pColumnRef->getChild(0);
+ if (SQL_ISRULE(pColumnRef,column_ref))
+ {
+ getColumnRange(pColumnRef,aColumnName,aTableRange);
+ DBG_ASSERT(aColumnName.Len(),"Columnname darf nicht leer sein");
+ }
+ else /*if (SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec) ||
+ SQL_ISRULE(pColumnRef,position_exp) || SQL_ISRULE(pColumnRef,extract_exp) ||
+ SQL_ISRULE(pColumnRef,length_exp) || SQL_ISRULE(pColumnRef,char_value_fct)||
+ SQL_ISRULE(pColumnRef,num_value_exp) || SQL_ISRULE(pColumnRef,term))*/
+ {
+ /* Funktionsaufruf vorhanden */
+ pColumnRef->parseNodeToStr(aColumnName,m_xDatabaseMetaData,NULL,FALSE,TRUE);
+
+ // gehoeren alle beteiligten Spalten der Funktion zu einer Tabelle
+ if (m_aTables.size() == 1)
+ {
+ aTableRange = m_aTables.begin()->first;
+ }
+ else
+ {
+ getColumnTableRange(pColumnRef,aTableRange);
+ }
+ bFkt = TRUE;
+ }
+ /*
+ else
+ {
+ aIteratorStatus.setStatementTooComplex();
+ return;
+ }
+ */
+ if(!aColumnAlias.Len())
+ aColumnAlias = aColumnName;
+ setSelectColumnName(aColumnName,aColumnAlias,aTableRange,bFkt);
+ }
+ }
+
+ } else
+ {
+ //aIteratorStatus.setInvalidStatement();
+ CallError(3);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseOrderByColumnNames(const OSQLParseNode* pSelectNode)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // aIteratorStatus.Clear();
+
+ if (pSelectNode == NULL)
+ {
+ //aIteratorStatus.setInvalidStatement();
+ CallError(3);
+ return;
+ }
+
+ if (m_eStatementType != SQL_STATEMENT_SELECT)
+ {
+ CallError(3);
+ //aIteratorStatus.setInvalidStatement();
+ return;
+ }
+
+ if(SQL_ISRULE(pSelectNode,union_statement))
+ {
+ traverseOrderByColumnNames(pSelectNode->getChild(0));
+ //traverseOrderByColumnNames(pSelectNode->getChild(3));
+ return;
+ }
+
+ DBG_ASSERT(pSelectNode->count() >= 4,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ OSQLParseNode * pTableExp = pSelectNode->getChild(3);
+ DBG_ASSERT(pTableExp != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pTableExp->count() == 5,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ OSQLParseNode * pOptOrderByClause = pTableExp->getChild(4);
+ DBG_ASSERT(pOptOrderByClause != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pOptOrderByClause,opt_order_by_clause),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ if (pOptOrderByClause->count() == 0)
+ return;
+
+ DBG_ASSERT(pOptOrderByClause->count() == 3,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ OSQLParseNode * pOrderingSpecCommalist = pOptOrderByClause->getChild(2);
+ DBG_ASSERT(pOrderingSpecCommalist != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pOrderingSpecCommalist,ordering_spec_commalist),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pOrderingSpecCommalist->count() > 0,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ String aColumnName,aColumnAlias;
+ String aTableRange;
+ for (UINT32 i = 0; i < pOrderingSpecCommalist->count(); i++)
+ {
+ OSQLParseNode * pOrderingSpec = pOrderingSpecCommalist->getChild(i);
+ DBG_ASSERT(pOrderingSpec != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pOrderingSpec,ordering_spec),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pOrderingSpec->count() == 2,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ OSQLParseNode * pColumnRef = pOrderingSpec->getChild(0);
+ aTableRange.Erase();
+ aColumnName.Erase();
+ if(SQL_ISRULE(pColumnRef,column_ref))
+ {
+ // Column-Name (und TableRange):
+ if(SQL_ISRULE(pColumnRef,column_ref))
+ getColumnRange(pColumnRef,aColumnName,aTableRange);
+ else // eine Expression
+ pColumnRef->parseNodeToStr(aColumnName,m_xDatabaseMetaData,NULL,FALSE,FALSE);
+
+ DBG_ASSERT(aColumnName.Len(),"aColumnName darf nicht leer sein");
+ }
+ else
+ { // here I found a predicate
+ pColumnRef->parseNodeToStr(aColumnName,m_xDatabaseMetaData,NULL,FALSE,FALSE);
+ }
+ DBG_ASSERT(pColumnRef != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ // Ascending/Descending
+ OSQLParseNode * pOptAscDesc = pOrderingSpec->getChild(1);
+ DBG_ASSERT(pOptAscDesc != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ BOOL bAscending = TRUE;
+ if(pOptAscDesc)
+ {
+ if (SQL_ISTOKEN(pOptAscDesc,ASC))
+ bAscending = TRUE;
+ else if (SQL_ISTOKEN(pOptAscDesc,DESC))
+ bAscending = FALSE;
+ }
+
+ setOrderByColumnName(aColumnName, aTableRange,bAscending);
+// if (! aIteratorStatus.IsSuccessful())
+// return;
+
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseSelectionCriteria(const OSQLParseNode* pSelectNode)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // aIteratorStatus.Clear();
+
+ if (pSelectNode == NULL)
+ {
+ CallError(3);
+ //aIteratorStatus.setInvalidStatement();
+ return;
+ }
+
+
+ // Parse Tree analysieren (je nach Statement-Typ)
+ // und Zeiger auf WHERE-Klausel setzen:
+ OSQLParseNode * pWhereClause = NULL;
+
+ if (m_eStatementType == SQL_STATEMENT_SELECT)
+ {
+ if(SQL_ISRULE(pSelectNode,union_statement))
+ {
+ traverseSelectionCriteria(pSelectNode->getChild(0));
+ traverseSelectionCriteria(pSelectNode->getChild(3));
+ return;
+ }
+ DBG_ASSERT(pSelectNode->count() >= 4,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ OSQLParseNode * pTableExp = pSelectNode->getChild(3);
+ DBG_ASSERT(pTableExp != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pTableExp->count() == 5,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ pWhereClause = pTableExp->getChild(1);
+ } else if (SQL_ISRULE(pSelectNode,update_statement_searched)) {
+ DBG_ASSERT(pSelectNode->count() == 5,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ pWhereClause = pSelectNode->getChild(4);
+ } else if (SQL_ISRULE(pSelectNode,update_statement_positioned)) {
+ // nyi
+ DBG_ERROR("OSQLParseTreeIterator::getSelectionCriteria: positioned nyi");
+ } else if (SQL_ISRULE(pSelectNode,delete_statement_searched)) {
+ DBG_ASSERT(pSelectNode->count() == 4,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ pWhereClause = pSelectNode->getChild(3);
+ } else if (SQL_ISRULE(pSelectNode,delete_statement_positioned)) {
+ // nyi
+ DBG_ERROR("OSQLParseTreeIterator::getSelectionCriteria: positioned nyi");
+ } else {
+ // Anderes Statement. Keine Selektionskriterien.
+ return;
+ }
+
+ if (! SQL_ISRULE(pWhereClause,where_clause)) {
+ // Die Where Clause ist meistens optional, d. h. es koennte sich auch
+ // um "optional_where_clause" handeln.
+ DBG_ASSERT(SQL_ISRULE(pWhereClause,opt_where_clause),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ return;
+ }
+
+ // Wenn es aber eine where_clause ist, dann darf sie nicht leer sein:
+ DBG_ASSERT(pWhereClause->count() == 2,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1);
+ DBG_ASSERT(pComparisonPredicate != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+
+ //
+ // Und nun die Vergleichskriterien abarbeiten (rekursiv, alles ist erstmal ein OR-Kriterium):
+ //
+ setORCriteriaPre();
+ // if (! aIteratorStatus.IsSuccessful()) return;
+
+ traverseORCriteria(pComparisonPredicate);
+ // if (! aIteratorStatus.IsSuccessful()) return;
+
+ setORCriteriaPost();
+
+ // Fehler wird ggf. einfach weitergereicht.
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseORCriteria(OSQLParseNode * pSearchCondition)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ if (
+ pSearchCondition->count() == 3 &&
+ SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")
+ )
+ {
+ // Runde Klammern um den Ausdruck
+ traverseORCriteria(pSearchCondition->getChild(1));
+ } else if (SQL_ISRULE(pSearchCondition,search_condition) &&
+ pSearchCondition->count() == 3 &&
+ SQL_ISTOKEN(pSearchCondition->getChild(1),OR))
+ {
+ // OR-Verknuepfung:
+
+ for (int i = 0; i < 3; i++) {
+ if (i == 1) continue; // Schluesselwort OR ueberspringen
+
+ // Ist das erste Element wieder eine OR-Verknuepfung?
+ if (i == 0 &&
+ SQL_ISRULE(pSearchCondition->getChild(0),search_condition) &&
+ pSearchCondition->getChild(0)->count() == 3 &&
+ SQL_ISTOKEN(pSearchCondition->getChild(0)->getChild(1),OR))
+ {
+ // Dann rekursiv absteigen ...
+ traverseORCriteria(pSearchCondition->getChild(0));
+
+ } else {
+ // AND-Kriterien ...
+ setANDCriteriaPre();
+ // if (! aIteratorStatus.IsSuccessful()) break;
+
+ traverseANDCriteria(pSearchCondition->getChild(i));
+ // if (! aIteratorStatus.IsSuccessful()) break;
+
+ setANDCriteriaPost();
+ }
+
+ // if (! aIteratorStatus.IsSuccessful()) break;
+ }
+ } else {
+ // Nur *ein* Kriterium oder eine AND-Verknuepfung von Kriterien.
+ // Direkt die AND-Kriterien behandeln.
+ setANDCriteriaPre();
+ // if (! aIteratorStatus.IsSuccessful()) return;
+
+ traverseANDCriteria(pSearchCondition);
+ // if (! aIteratorStatus.IsSuccessful()) return;
+
+ setANDCriteriaPost();
+ }
+
+ // Fehler einfach weiterreichen.
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ if (
+ SQL_ISRULE(pSearchCondition,boolean_primary) &&
+ pSearchCondition->count() == 3 &&
+ SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")
+ )
+ {
+ // Runde Klammern
+ traverseANDCriteria(pSearchCondition->getChild(1));
+ }
+ // Das erste Element ist eine OR-Verknuepfung
+ else if ( SQL_ISRULE(pSearchCondition,search_condition) && pSearchCondition->count() == 3 )
+ {
+ // Dann rekursiv absteigen (dieselbe Row benutzen) ...
+ traverseORCriteria(pSearchCondition->getChild(0));
+// if (! aIteratorStatus.IsSuccessful())
+// return;
+
+ // Und mit dem rechten Child weitermachen:
+ traverseANDCriteria(pSearchCondition->getChild(2));
+ }
+ // Das erste Element ist (wieder) eine AND-Verknuepfung
+ else if ( SQL_ISRULE(pSearchCondition,boolean_term) && pSearchCondition->count() == 3 )
+ {
+ // Dann rekursiv absteigen (dieselbe Row benutzen) ...
+ traverseANDCriteria(pSearchCondition->getChild(0));
+// if (! aIteratorStatus.IsSuccessful())
+// return;
+
+ // Und mit dem rechten Child weitermachen:
+ traverseANDCriteria(pSearchCondition->getChild(2));
+ }
+ // Sonst einzelne Suchkriterien wie =, !=, ..., LIKE, IS NULL usw. behandeln:
+ else if (SQL_ISRULE(pSearchCondition,comparison_predicate) )
+ {
+ OSQLPredicateType ePredicateType;
+ OSQLParseNode *pPrec = pSearchCondition->getChild(1);
+ if (pPrec->getNodeType() == SQL_NODE_EQUAL)
+ ePredicateType = SQL_PRED_EQUAL;
+ else if (pPrec->getNodeType() == SQL_NODE_NOTEQUAL)
+ ePredicateType = SQL_PRED_NOTEQUAL;
+ else if (pPrec->getNodeType() == SQL_NODE_LESS)
+ ePredicateType = SQL_PRED_LESS;
+ else if (pPrec->getNodeType() == SQL_NODE_LESSEQ)
+ ePredicateType = SQL_PRED_LESSOREQUAL;
+ else if (pPrec->getNodeType() == SQL_NODE_GREATEQ)
+ ePredicateType = SQL_PRED_GREATEROREQUAL;
+ else if (pPrec->getNodeType() == SQL_NODE_GREAT)
+ ePredicateType = SQL_PRED_GREATER;
+
+ String aValue;
+ pSearchCondition->getChild(2)->parseNodeToStr(aValue,m_xDatabaseMetaData,NULL,FALSE,FALSE);
+ traverseOnePredicate(pSearchCondition->getChild(0),ePredicateType,aValue,FALSE,pSearchCondition->getChild(2));
+// if (! aIteratorStatus.IsSuccessful())
+// return;
+ }
+ else if (SQL_ISRULE(pSearchCondition,like_predicate) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
+ {
+ OSQLPredicateType ePredicateType;
+
+ DBG_ASSERT(pSearchCondition->count() >= 5,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ OSQLParseNode * pNum_value_exp = pSearchCondition->getChild(3);
+ OSQLParseNode * pOptEscape = pSearchCondition->getChild(4);
+
+ if (pSearchCondition->getChild(1)->getTokenID() == SQL_TOKEN_NOT)
+ ePredicateType = SQL_PRED_NOTLIKE;
+ else
+ ePredicateType = SQL_PRED_LIKE;
+
+ DBG_ASSERT(pNum_value_exp != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pOptEscape != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ if (pOptEscape->count() != 0)
+ {
+ // aIteratorStatus.setStatementTooComplex();
+ return;
+ }
+
+ String aValue;
+ OSQLParseNode * pParam = NULL;
+ if (SQL_ISRULE(pNum_value_exp,parameter))
+ pParam = pNum_value_exp;
+ else if(pNum_value_exp->isToken())
+ // Normaler Wert
+ aValue = pNum_value_exp->getTokenValue();
+ else
+ {
+ pNum_value_exp->parseNodeToStr(aValue,m_xDatabaseMetaData,NULL,FALSE,FALSE);
+ pParam = pNum_value_exp;
+ }
+
+ traverseOnePredicate(pSearchCondition->getChild(0),ePredicateType,aValue,FALSE,pParam);
+// if (! aIteratorStatus.IsSuccessful())
+// return;
+ }
+ else if (SQL_ISRULE(pSearchCondition,test_for_null) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
+ {
+ OSQLPredicateType ePredicateType;
+
+ DBG_ASSERT(pSearchCondition->count() >= 3,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISTOKEN(pSearchCondition->getChild(1),IS),"OSQLParseTreeIterator: Fehler im Parse Tree")
+
+ if (SQL_ISTOKEN(pSearchCondition->getChild(2),NOT) )
+ ePredicateType = SQL_PRED_ISNOTNULL;
+ else
+ ePredicateType = SQL_PRED_ISNULL;
+
+ String aString;
+ traverseOnePredicate(pSearchCondition->getChild(0),ePredicateType,aString,TRUE,NULL);
+ // if (! aIteratorStatus.IsSuccessful()) return;
+ } else {
+ // Etwas anderes unterstuetzen wir (noch) nicht. Basta!
+ // aIteratorStatus.setStatementTooComplex();
+ }
+ // Fehler einfach weiterreichen.
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseOnePredicate(
+ OSQLParseNode * pColumnRef,
+ OSQLPredicateType ePredicateType,
+ String& rValue,
+ BOOL bCompareNull,
+ OSQLParseNode * pParseNode)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ // Column-Name (und TableRange):
+ String aColumnName;
+ String aTableRange;
+ getColumnRange(pColumnRef,aColumnName,aTableRange);
+
+ String aName;
+ if (pParseNode) //event. Parameter, oder Columnref oder
+ {
+ if (SQL_ISRULE(pParseNode,parameter))
+ {
+ DBG_ASSERT(pParseNode->count() > 0,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ OSQLParseNode * pMark = pParseNode->getChild(0);
+
+ String aParameterName;
+ if (SQL_ISPUNCTUATION(pMark,"?"))
+ {
+ // Name = "?", da kein Parametername verfuegbar (z. B. bei Native SQL)
+ rValue = '?';
+ aName = '?';
+ }
+ else if (SQL_ISPUNCTUATION(pMark,":"))
+ {
+ rValue = pParseNode->getChild(1)->getTokenValue();
+ aName = ':';
+ }
+ else if (SQL_ISPUNCTUATION(pMark,"["))
+ {
+ rValue = pParseNode->getChild(1)->getTokenValue();
+ aName = '[';
+ }
+ else
+ {
+ DBG_ERROR("OSQLParseTreeIterator: Fehler im Parse Tree");
+ }
+ }
+ else if (SQL_ISRULE(pParseNode,column_ref))// Column-Name (und TableRange):
+ getColumnRange(pParseNode,aName,rValue);
+ }
+
+ // "set"-Routine aufrufen ...
+ if (bCompareNull) {
+ // nyi: was soll das? Vergleich auf NULL geht nur ueber IS NULL oder IS NOT NULL!
+ setPredicate(aColumnName, aTableRange,ePredicateType, String(), String());
+ } else {
+ setPredicate(aColumnName, aTableRange, ePredicateType, rValue, aName);
+ }
+
+ // Fehler einfach weiterreichen ...
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseAssignments()
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ DBG_ERROR("OSQLParseTreeIterator::traverseAssignments: noch nicht implementiert");
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseAll()
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ traverseTableNames();
+ // if (! aIteratorStatus.IsSuccessful()) return;
+
+ if (m_eStatementType == SQL_STATEMENT_SELECT)
+ {
+ const OSQLParseNode* pSelectNode = m_pParseTree;
+ traverseSelectColumnNames(pSelectNode);
+// if (! aIteratorStatus.IsSuccessful())
+// return;
+ traverseOrderByColumnNames(pSelectNode);
+// if (! aIteratorStatus.IsSuccessful())
+// return;
+ traverseSelectionCriteria(pSelectNode);
+ // if (! aIteratorStatus.IsSuccessful())
+ // return;
+ }
+ else if (m_eStatementType == SQL_STATEMENT_INSERT || m_eStatementType == SQL_STATEMENT_UPDATE)
+ {
+ traverseAssignments();
+ // if (! aIteratorStatus.IsSuccessful())
+ // return;
+ } else if (m_eStatementType == SQL_STATEMENT_INSERT) {
+ // schon alles erledigt
+ } else {
+ CallError(3);
+ //aIteratorStatus.setInvalidStatement();
+ }
+}
+
+// Dummy-Implementationen:
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setTableName(const String & rTableName, const String & rDBName, const String& rOwner,
+ const String & rTableRange)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // nichts zu tun ...
+
+#ifdef SQL_TEST_PARSETREEITERATOR
+ cout << "OSQLParseTreeIterator::setTableName"
+ << (const char *) rTableName << ", "
+ << (const char *) rSchemaName << ", "
+ << (const char *) rTableRange
+ << "\n";
+#endif
+}
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::appendColumns(const OSQLTable& _rTable)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ if (!_rTable.is())
+ return;
+
+ Reference<XNameAccess> xColumns = _rTable->getColumns();
+
+ Sequence< ::rtl::OUString > aColNames = xColumns->getElementNames();
+ const ::rtl::OUString* pBegin = aColNames.getConstArray();
+ const ::rtl::OUString* pEnd = pBegin + aColNames.getLength();
+
+ for(;pBegin != pEnd;++pBegin)
+ {
+ OSQLColumns::const_iterator aIter = find(m_aSelectColumns->begin(),m_aSelectColumns->end(),*pBegin,m_aCaseEqual);
+ ::rtl::OUString aName(*pBegin);
+ sal_Int32 i=1;
+ while(aIter != m_aSelectColumns->end())
+ {
+ aName = *pBegin + ::rtl::OUString::valueOf(i++);
+ aIter = find(m_aSelectColumns->begin(),m_aSelectColumns->end(),aName,m_aCaseEqual);
+ }
+ Reference< XFastPropertySet > xColumn;
+ if(xColumns->getByName(*pBegin) >>= xColumn)
+ {
+ OParseColumn* pColumn = new OParseColumn(xColumn,m_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers());
+ // pColumn->setTableName(aIter->first);
+ pColumn->setRealName(aName);
+ Reference< XFastPropertySet> xCol = pColumn;
+ m_aSelectColumns->push_back(xCol);
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setSelectColumnName(const String & rColumnName,const String & rColumnAlias, const String & rTableRange,BOOL bFkt)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ if(rColumnName.GetChar(0) == '*' && !rTableRange.Len())
+ { // Suche "uber alle vorkommenden Tabellen
+ for(ConstOSQLTablesIterator aIter = m_aTables.begin(); aIter != m_aTables.end();++aIter)
+ appendColumns(aIter->second);
+ }
+ else if(rColumnName.GetChar(0) == '*' && rTableRange.Len()) // alle Columns aus dieser Tabelle
+ {
+ ConstOSQLTablesIterator aFind = m_aTables.find(rTableRange);
+
+ if(aFind == m_aTables.end())
+ {
+ String strExpression = rTableRange;
+ strExpression += '.';
+ strExpression += rColumnName;
+ CallError(2, strExpression);
+ }
+ else
+ appendColumns(aFind->second);
+ }
+ else if(!rTableRange.Len())// ein Columnname existiert
+ {
+ if(!bFkt)
+ {
+
+ UINT32 ncount = m_aSelectColumns->size();
+ for(OSQLTablesIterator aIter = m_aTables.begin(); aIter != m_aTables.end(); ++aIter)
+ {
+ if (aIter->second.is())
+ {
+ Reference<XNameAccess> xColumns = aIter->second->getColumns();
+
+ Reference< XFastPropertySet > xColumn;
+ if(xColumns->getByName(rColumnName) >>= xColumn)
+ {
+ String aNewColName(getUniqueColumnName(rColumnAlias));
+
+ OParseColumn* pColumn = new OParseColumn(xColumn,m_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers());
+ pColumn->setTableName(aIter->first);
+ pColumn->setName(aNewColName);
+ pColumn->setRealName(rColumnName);
+
+ Reference< XFastPropertySet> xCol = pColumn;
+ m_aSelectColumns->push_back(xCol);
+ continue; // diese Column darf nur einmal vorkommen
+ }
+ }
+ }
+ if (ncount == m_aSelectColumns->size())
+ {
+ String strExpression = rTableRange;
+ if (strExpression.Len())
+ strExpression += '.';
+ strExpression += rColumnName;
+ CallError(2, strExpression);
+ }
+ }
+ else
+ {
+ String aNewColName(getUniqueColumnName(rColumnAlias));
+
+ OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),
+ ColumnValue::NULLABLE_UNKNOWN,0,0,DataType::VARCHAR,sal_False,sal_False,m_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers());
+ pColumn->setFunction(bFkt);
+ pColumn->setRealName(rColumnName);
+
+ Reference< XFastPropertySet> xCol = pColumn;
+ m_aSelectColumns->push_back(xCol);
+ }
+ }
+ else // ColumnName und Tablename vorhanden
+ {
+ ConstOSQLTablesIterator aFind = m_aTables.find(rTableRange);
+
+ BOOL bError = FALSE;
+ if (aFind->second.is())
+ {
+
+ if (bFkt)
+ {
+ String aNewColName(getUniqueColumnName(rColumnAlias));
+
+ OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),
+ ColumnValue::NULLABLE_UNKNOWN,0,0,DataType::VARCHAR,sal_False,sal_False,m_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers());
+ pColumn->setFunction(sal_True);
+ pColumn->setRealName(rColumnName);
+ pColumn->setTableName(aFind->first);
+
+ Reference< XFastPropertySet> xCol = pColumn;
+ m_aSelectColumns->push_back(xCol);
+ }
+ else
+ {
+ Reference< XFastPropertySet > xColumn;
+ if (aFind->second->getColumns()->getByName(rColumnName) >>= xColumn)
+ {
+ String aNewColName(getUniqueColumnName(rColumnAlias));
+
+ OParseColumn* pColumn = new OParseColumn(xColumn,m_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers());
+ pColumn->setName(aNewColName);
+ pColumn->setRealName(rColumnName);
+ pColumn->setTableName(aFind->first);
+
+ Reference< XFastPropertySet> xCol = pColumn;
+ m_aSelectColumns->push_back(xCol);
+ }
+ else
+ bError = TRUE;
+ }
+ }
+ else
+ bError = TRUE;
+
+ // Tabelle existiert nicht oder Feld nicht vorhanden
+ if (bError)
+ {
+ String strExpression = rTableRange;
+ if (strExpression.Len())
+ strExpression += '.';
+ strExpression += rColumnName;
+ if (!CallError(2, strExpression))
+ return;
+
+ String aNewColName(getUniqueColumnName(rColumnAlias));
+
+ OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),
+ ColumnValue::NULLABLE_UNKNOWN,0,0,DataType::VARCHAR,sal_False,sal_False,m_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers());
+ pColumn->setFunction(sal_True);
+
+
+ Reference< XFastPropertySet> xCol = pColumn;
+ m_aSelectColumns->push_back(xCol);
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+String OSQLParseTreeIterator::getUniqueColumnName(const String & rColumnName) const
+{
+ ::rtl::OUString aAlias(rColumnName);
+
+ OSQLColumns::const_iterator aIter = find(m_aSelectColumns->begin(),m_aSelectColumns->end(),aAlias,m_aCaseEqual);
+ sal_Int32 i=1;
+ while(aIter != m_aSelectColumns->end())
+ {
+ (aAlias = rColumnName) += ::rtl::OUString::valueOf(i++);
+ aIter = find(m_aSelectColumns->begin(),m_aSelectColumns->end(),aAlias,m_aCaseEqual);
+ }
+ return aAlias;
+}
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setOrderByColumnName(const String & rColumnName, const String & rTableRange,BOOL bAscending)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // nichts zu tun ...
+
+#ifdef SQL_TEST_PARSETREEITERATOR
+ cout << "OSQLParseTreeIterator::setOrderByColumnName: "
+ << (const char *) rColumnName << ", "
+ << (const char *) rTableRange << ", "
+ << (bAscending ? "TRUE" : "FALSE")
+ << "\n";
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setORCriteriaPre()
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // nichts zu tun ...
+
+#ifdef SQL_TEST_PARSETREEITERATOR
+ cout << "OSQLParseTreeIterator::setORCriteriaPre\n";
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setORCriteriaPost()
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // nichts zu tun ...
+
+#ifdef SQL_TEST_PARSETREEITERATOR
+ cout << "OSQLParseTreeIterator::setORCriteriaPost\n";
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setANDCriteriaPre()
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // nichts zu tun ...
+
+#ifdef SQL_TEST_PARSETREEITERATOR
+ cout << "OSQLParseTreeIterator::setANDCriteriaPre\n";
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setANDCriteriaPost()
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // nichts zu tun ...
+
+#ifdef SQL_TEST_PARSETREEITERATOR
+ cout << "OSQLParseTreeIterator::setANDCriteriaPost\n";
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setPredicate(const String & rColumnName,
+ const String & rTableRange,
+ OSQLPredicateType ePredicateType,
+ const String & rValue,
+ const String & rParameterName)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // nichts zu tun ...
+
+#ifdef SQL_TEST_PARSETREEITERATOR
+ cout << "OSQLParseTreeIterator::setPredicate: "
+ << (const char *) rColumnName << ", "
+ << (const char *) rTableRange << ", "
+ << (char) ePredicateType << ", "
+ << (const char *) rValue << ", "
+ << (const char *) rParameterName
+ << "\n";
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::setAssign(const String & rColumnName,
+ const String & rValue, BOOL bsetNull,
+ const String & rParameterName)
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+ // nichts zu tun ...
+
+#ifdef SQL_TEST_PARSETREEITERATOR
+ cout << "OSQLParseTreeIterator::setAssign: "
+ << (const char *) rColumnName << ", "
+ << (const char *) rValue << ", "
+ << (bsetNull ? "TRUE" : "FALSE") << ", "
+ << (const char *) rParameterName
+ << "\n";
+#endif
+}
+
+//-----------------------------------------------------------------------------
+const OSQLParseNode* OSQLParseTreeIterator::getWhereTree() const
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ if (!m_pParseTree)
+ return NULL;
+
+ // Parse Tree analysieren (je nach Statement-Typ)
+ // und Zeiger auf WHERE-Klausel setzen:
+ OSQLParseNode * pWhereClause = NULL;
+ if(getStatementType() == SQL_STATEMENT_SELECT)
+ {
+ DBG_ASSERT(m_pParseTree->count() >= 4,"ParseTreeIterator: Fehler im Parse Tree");
+ OSQLParseNode * pTableExp = m_pParseTree->getChild(3);
+ DBG_ASSERT(pTableExp != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pTableExp->count() == 5,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ pWhereClause = pTableExp->getChild(1);
+ }
+ else if (SQL_ISRULE(m_pParseTree,update_statement_searched) ||
+ SQL_ISRULE(m_pParseTree,delete_statement_searched))
+ {
+ pWhereClause = m_pParseTree->getChild(m_pParseTree->count()-1);
+ }
+ if(pWhereClause->count() != 2)
+ pWhereClause = NULL;
+ return pWhereClause;
+}
+
+//-----------------------------------------------------------------------------
+const OSQLParseNode* OSQLParseTreeIterator::getOrderTree() const
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT)
+ return NULL;
+
+ // Parse Tree analysieren (je nach Statement-Typ)
+ // und Zeiger auf ORDER-Klausel setzen:
+ OSQLParseNode * pOrderClause = NULL;
+ DBG_ASSERT(m_pParseTree->count() >= 4,"ParseTreeIterator: Fehler im Parse Tree");
+ OSQLParseNode * pTableExp = m_pParseTree->getChild(3);
+ DBG_ASSERT(pTableExp != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pTableExp->count() == 5,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ pOrderClause = pTableExp->getChild(4);
+ // Wenn es aber eine order_by ist, dann darf sie nicht leer sein:
+ if(pOrderClause->count() != 3)
+ pOrderClause = NULL;
+ return pOrderClause;
+}
+//-----------------------------------------------------------------------------
+const OSQLParseNode* OSQLParseTreeIterator::getGroupByTree() const
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT)
+ return NULL;
+
+ // Parse Tree analysieren (je nach Statement-Typ)
+ // und Zeiger auf ORDER-Klausel setzen:
+ OSQLParseNode * pGroupClause = NULL;
+ DBG_ASSERT(m_pParseTree->count() >= 4,"ParseTreeIterator: Fehler im Parse Tree");
+ OSQLParseNode * pTableExp = m_pParseTree->getChild(3);
+ DBG_ASSERT(pTableExp != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pTableExp->count() == 5,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ pGroupClause = pTableExp->getChild(3);
+ // Wenn es aber eine order_by ist, dann darf sie nicht leer sein:
+ if(pGroupClause->count() != 3)
+ pGroupClause = NULL;
+ return pGroupClause;
+}
+//-----------------------------------------------------------------------------
+const OSQLParseNode* OSQLParseTreeIterator::getHavingTree() const
+{
+ DBG_CHKTHIS(OSQLParseTreeIterator,NULL);
+
+ if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT)
+ return NULL;
+
+ // Parse Tree analysieren (je nach Statement-Typ)
+ // und Zeiger auf ORDER-Klausel setzen:
+ OSQLParseNode * pHavingClause = NULL;
+ DBG_ASSERT(m_pParseTree->count() >= 4,"ParseTreeIterator: Fehler im Parse Tree");
+ OSQLParseNode * pTableExp = m_pParseTree->getChild(3);
+ DBG_ASSERT(pTableExp != NULL,"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: Fehler im Parse Tree");
+ DBG_ASSERT(pTableExp->count() == 5,"OSQLParseTreeIterator: Fehler im Parse Tree");
+
+ pHavingClause = pTableExp->getChild(3);
+ // Wenn es aber eine order_by ist, dann darf sie nicht leer sein:
+ if(pHavingClause->count() < 1)
+ pHavingClause = NULL;
+ return pHavingClause;
+}
+//-----------------------------------------------------------------------------
+BOOL OSQLParseTreeIterator::CallError(USHORT nError,const String& rExpression)
+{
+// SdbParseIteratorErrorInfo aErrorInfo;
+// aErrorInfo.aStatus = rStatus;
+// aErrorInfo.nErrorCode = nError;
+// aErrorInfo.aExpression = rExpression;
+//
+// long nResult = aErrorHdl.Call(&aErrorInfo);
+// if (nResult == RET_CONTINUE)
+ return TRUE;
+
+// if (nResult == RET_HANDLED)
+// {
+// // aIteratorStatus.set(SQL_STAT_SUCCESS);
+// return FALSE;
+// }
+//
+// aIteratorStatus = rStatus;
+// return FALSE;
+//
+}
+
diff --git a/connectivity/source/parse/sqlnode.cxx b/connectivity/source/parse/sqlnode.cxx
new file mode 100644
index 000000000000..f35c06bf8f25
--- /dev/null
+++ b/connectivity/source/parse/sqlnode.cxx
@@ -0,0 +1,1399 @@
+/*************************************************************************
+ *
+ * $RCSfile: sqlnode.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:14:28 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _CONNECTIVITY_SQLNODE_HXX
+#include <connectivity/sqlnode.hxx>
+#endif
+#ifndef _CONNECTIVITY_SQLPARSE_HXX
+#include <connectivity/sqlparse.hxx>
+#endif
+#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
+#include <com/sun/star/lang/Locale.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#endif
+#ifndef _TOOLS_INTN_HXX //autogen wg. International
+#include <tools/intn.hxx>
+#endif
+#ifndef _ISOLANG_HXX
+#include <tools/isolang.hxx>
+#endif
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::osl;
+using namespace connectivity;
+
+extern Any getNumberFormatProperty(const Reference< XNumberFormatsSupplier > & xFormatter,
+ sal_Int32 nKey,
+ const rtl::OUString& );
+extern double ToDouble(const Time& rTime);
+extern double ToDouble(const Reference< XNumberFormatsSupplier > & xSupplier, const Date& rDate);
+extern String ConvertLikeToken(const OSQLParseNode* pTokenNode, const OSQLParseNode* pEscapeNode, sal_Bool bInternational);
+
+//------------------------------------------------------------------
+OSQLParseNode::SQLParseNodeParameter::SQLParseNodeParameter(const String& _rIdentifierQuote, const String& _rCatalogSep,
+ const Reference< XNumberFormatter > & _xFormatter, const Reference< XPropertySet > & _xField, const International& _rIntl,
+ const OParseContext* _pContext, sal_Bool _bIntl, sal_Bool _bQuote, char _cDecSep,
+ sal_Bool _bPredicate)
+ :aIdentifierQuote(_rIdentifierQuote)
+ ,aCatalogSeparator(_rCatalogSep)
+ ,rIntl(_rIntl)
+ ,rContext(_pContext ? *_pContext : OSQLParser::s_aDefaultContext)
+ ,bInternational(_bIntl)
+ ,bQuote(_bQuote)
+ ,cDecSep(_cDecSep)
+ ,xField(_xField)
+ ,xFormatter(_xFormatter)
+ ,bPredicate(_bPredicate)
+{
+}
+
+//------------------------------------------------------------------
+String SetQuotation(const String& rValue, const String& rQuot, const String& rQuotToReplace)
+{
+ String rNewValue = rQuot;
+ rNewValue += rValue;
+
+ xub_StrLen nIndex = (xub_StrLen)-1; // Quotes durch zweifache Quotes ersetzen, sonst kriegt der Parser Probleme
+
+ if (rQuot.Len())
+ {
+ do
+ {
+ nIndex+= 2;
+ nIndex = rNewValue.SearchAndReplace(rQuot,rQuotToReplace,nIndex);
+ } while (nIndex != STRING_NOTFOUND);
+ }
+ // rNewValue.SearchAndReplaceAll(rQuot,rQuotToReplace);
+
+ rNewValue += rQuot;
+ return rNewValue;
+}
+
+
+//-----------------------------------------------------------------------------
+String OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const String& rString) const
+{
+ xub_StrLen nIndex = 0;
+ sal_Int32 nYear = rString.GetToken(0,'-', nIndex).ToInt32(),
+ nMonth = rString.GetToken(0,'-', nIndex).ToInt32(),
+ nDay = rString.GetToken(0,'-', nIndex).ToInt32();
+
+ Date aDate(nDay,nMonth,nYear);
+ Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
+ Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
+
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry);
+ Locale aLocale(sLanguage,sCountry,rtl::OUString());
+
+ double fDate = ToDouble(xSupplier, aDate);
+ sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 36; // XXX hack
+ return rParam.xFormatter->convertNumberToString(nKey, fDate);
+}
+
+//-----------------------------------------------------------------------------
+String OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rParam, const String& rString) const
+{
+ xub_StrLen nIndex = 0;
+ sal_Int32 nYear = rString.GetToken(0,'-', nIndex).ToInt32(),
+ nMonth = rString.GetToken(0,'-', nIndex).ToInt32(),
+ nDay = rString.GetToken(0,'-', nIndex).ToInt32();
+
+ nIndex = 10; // eat white space
+ sal_Int32 nHour = rString.GetToken(0,':', nIndex).ToInt32(),
+ nMinute = rString.GetToken(0,':', nIndex).ToInt32(),
+ nSecond = rString.GetToken(0,':', nIndex).ToInt32();
+
+ Date aDate(nDay,nMonth,nYear);
+ Time aTime(nHour,nMinute,nSecond);
+ Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
+ Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
+
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry);
+ Locale aLocale(sLanguage,sCountry,rtl::OUString());
+
+ double fDateTime = ToDouble(xSupplier, aDate) + ToDouble(aTime);
+ sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 51; // XXX hack
+ return rParam.xFormatter->convertNumberToString(nKey, fDateTime);
+}
+
+//-----------------------------------------------------------------------------
+String OSQLParseNode::convertTimeString(const SQLParseNodeParameter& rParam, const String& rString) const
+{
+ xub_StrLen nIndex = 0;
+ sal_Int32 nHour = rString.GetToken(0,':', nIndex).ToInt32(),
+ nMinute = rString.GetToken(0,':', nIndex).ToInt32(),
+ nSecond = rString.GetToken(0,':', nIndex).ToInt32();
+
+ Time aTime(nHour,nMinute,nSecond);
+ Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
+
+ Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
+
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry);
+ Locale aLocale(sLanguage,sCountry,rtl::OUString());
+
+ double fTime = ToDouble(aTime);
+ sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 41; // XXX hack
+ return rParam.xFormatter->convertNumberToString(nKey, fTime);
+}
+
+DBG_NAME(OSQLParseNode);
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const sal_Char * pNewValue,
+ SQLNodeType eNewNodeType,
+ sal_uInt32 nNewNodeID)
+ : m_aNodeValue(String::CreateFromAscii(pNewValue))
+ , m_eNodeType(eNewNodeType)
+ , m_nNodeID(nNewNodeID)
+ , m_pParent(NULL)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert");
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const ByteString &_rNewValue,
+ SQLNodeType eNewNodeType,
+ sal_uInt32 nNewNodeID)
+ : m_aNodeValue(String::CreateFromAscii(_rNewValue.GetBuffer()))
+ , m_eNodeType(eNewNodeType)
+ , m_nNodeID(nNewNodeID)
+ , m_pParent(NULL)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert");
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const sal_Unicode * pNewValue,
+ SQLNodeType eNewNodeType,
+ sal_uInt32 nNewNodeID)
+ : m_aNodeValue(pNewValue)
+ , m_eNodeType(eNewNodeType)
+ , m_nNodeID(nNewNodeID)
+ , m_pParent(NULL)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert");
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const String &_rNewValue,
+ SQLNodeType eNewNodeType,
+ sal_uInt32 nNewNodeID)
+ : m_aNodeValue(_rNewValue)
+ , m_eNodeType(eNewNodeType)
+ , m_nNodeID(nNewNodeID)
+ , m_pParent(NULL)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert");
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const OSQLParseNode& rParseNode)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ // klemm den getParent auf NULL
+ m_pParent = NULL;
+
+ // kopiere die member
+ m_aNodeValue = rParseNode.m_aNodeValue;
+ m_eNodeType = rParseNode.m_eNodeType;
+ m_nNodeID = rParseNode.m_nNodeID;
+
+
+ // denk dran, dass von Container abgeleitet wurde, laut SV-Help erzeugt
+ // copy-Constructor des Containers einen neuen Container mit den gleichen
+ // Zeigern als Inhalt -> d.h. nach dem Kopieren des Container wird fuer
+ // alle Zeiger ungleich NULL eine Kopie hergestellt und anstelle des alten
+ // Zeigers wieder eingehangen.
+
+ // wenn kein Blatt, dann SubTrees bearbeiten
+ for (::std::vector<OSQLParseNode*>::const_iterator i = rParseNode.m_aChilds.begin();
+ i != rParseNode.m_aChilds.end(); i++)
+ append(new OSQLParseNode(**i));
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode& OSQLParseNode::operator=(const OSQLParseNode& rParseNode)
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+
+ if (this != &rParseNode)
+ {
+ // kopiere die member - pParent bleibt der alte
+ m_aNodeValue = rParseNode.m_aNodeValue;
+ m_eNodeType = rParseNode.m_eNodeType;
+ m_nNodeID = rParseNode.m_nNodeID;
+
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ i != m_aChilds.end(); i++)
+ delete *i;
+
+ m_aChilds.clear();
+
+ for (::std::vector<OSQLParseNode*>::const_iterator j = rParseNode.m_aChilds.begin();
+ j != rParseNode.m_aChilds.end(); j++)
+ append(new OSQLParseNode(**j));
+ }
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool OSQLParseNode::operator==(OSQLParseNode& rParseNode) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+
+ // die member muessen gleich sein
+ sal_Bool bResult = (m_nNodeID == rParseNode.m_nNodeID) &&
+ (m_eNodeType == rParseNode.m_eNodeType) &&
+ (m_aNodeValue == rParseNode.m_aNodeValue) &&
+ count() == rParseNode.count();
+
+ // Parameters are not equal!
+ bResult = bResult && !SQL_ISRULE(this, parameter);
+
+ // compare childs
+ for (sal_uInt32 i=0; bResult && i < count(); i++)
+ bResult = *getChild(i) == *rParseNode.getChild(i);
+
+ return bResult;
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode::~OSQLParseNode()
+{
+ DBG_DTOR(OSQLParseNode,NULL);
+
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ i != m_aChilds.end(); i++)
+ delete *i;
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::append(OSQLParseNode* pNewNode)
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ DBG_ASSERT(pNewNode != NULL, "OSQLParseNode: ungueltiger NewSubTree");
+ DBG_ASSERT(pNewNode->getParent() == NULL, "OSQLParseNode: Knoten ist kein Waise");
+ DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewNode) == m_aChilds.end(),
+ "OSQLParseNode::append() Node already element of parent");
+
+ // stelle Verbindung zum getParent her:
+ pNewNode->setParent( this );
+ // und haenge den SubTree hinten an
+ m_aChilds.push_back(pNewNode);
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToStr(String& rString,
+ const Reference< XDatabaseMetaData > & xMeta,
+ OParseContext* pContext,
+ sal_Bool _bIntl,
+ sal_Bool _bQuote) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ parseNodeToStr(rString, xMeta, Reference< XNumberFormatter >(),
+ Reference< XPropertySet >(), OParseContext::getDefaultInternational(), pContext, _bIntl, _bQuote, '.', sal_False);
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToPredicateStr(String& rString,
+ const Reference< XDatabaseMetaData > & xMeta,
+ const Reference< XNumberFormatter > & xFormatter,
+ const International& rIntl,
+ OParseContext* pContext ) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ DBG_ASSERT(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
+
+ if (xFormatter.is())
+ parseNodeToStr(rString, xMeta, xFormatter, Reference< XPropertySet >(), rIntl, pContext, sal_True, sal_True, rIntl.GetNumDecimalSep(), sal_True);
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToPredicateStr(String& rString,
+ const Reference< XDatabaseMetaData > & xMeta,
+ const Reference< XNumberFormatter > & xFormatter,
+ const Reference< XPropertySet > & _xField,
+ const International& rIntl,
+ OParseContext* pContext ) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ DBG_ASSERT(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
+
+ if (xFormatter.is())
+ parseNodeToStr(rString, xMeta, xFormatter, _xField, rIntl, pContext, sal_True, sal_True, rIntl.GetNumDecimalSep(), sal_True);
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToStr(String& rString,
+ const Reference< XDatabaseMetaData > & xMeta,
+ const Reference< XNumberFormatter > & xFormatter,
+ const Reference< XPropertySet > & _xField,
+ const International& rIntl,
+ OParseContext* pContext,
+ sal_Bool _bIntl,
+ sal_Bool _bQuote,
+ char _cDecSep,
+ sal_Bool bPredicate) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ DBG_ASSERT(xMeta.is(), "OSQLParseNode::parseNodeToStr:: no meta data!");
+
+ if (xMeta.is())
+ {
+ String aIdentifierQuote(xMeta->getIdentifierQuoteString());
+ String aCatalogSeparator(xMeta->getCatalogSeparator());
+
+ OSQLParseNode::parseNodeToStr(rString,
+ SQLParseNodeParameter(aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, rIntl, pContext, _bIntl, _bQuote, _cDecSep, bPredicate));
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+
+ if (!isToken())
+ {
+ // einmal auswerten wieviel Subtrees dieser Knoten besitzt
+ sal_uInt32 nCount = count();
+
+ // parameter erhalten sonderbehandlung
+ if (SQL_ISRULE(this,parameter))
+ {
+ if(rString.Len())
+ rString += ' ';
+ if (nCount == 1) // ?
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ else if (nCount == 2) // :Name
+ {
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ rString += m_aChilds[1]->m_aNodeValue;
+ } // [Name]
+ else
+ {
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ rString += m_aChilds[1]->m_aNodeValue;
+ rString += m_aChilds[2]->m_aNodeValue;
+ }
+ }
+
+ else if(SQL_ISRULE(this,table_ref) &&
+ ((nCount == 4 && SQL_ISPUNCTUATION(m_aChilds[0],"("))|| (nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"("))))
+ tableRangeNodeToStr(rString, rParam);
+ // je nachdem ob international angegeben wird oder nicht wird like anders behandelt
+ // interanational: *, ? sind Platzhalter
+ // sonst SQL92 konform: %, _
+ else if (SQL_ISRULE(this,like_predicate))
+ likeNodeToStr(rString, rParam);
+
+ else if (SQL_ISRULE(this,general_set_fct) || SQL_ISRULE(this,set_fct_spec) ||
+ SQL_ISRULE(this,position_exp) || SQL_ISRULE(this,extract_exp) ||
+ SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct))
+ {
+ if (!addDateValue(rString, rParam))
+ {
+ // Funktionsname nicht quoten
+ SQLParseNodeParameter aNewParam(rParam);
+ aNewParam.bQuote = sal_False;
+
+ m_aChilds[0]->parseNodeToStr(rString, aNewParam);
+ String aStringPara;
+ for (sal_uInt32 i=1; i<nCount; i++)
+ {
+ const OSQLParseNode * pSubTree = m_aChilds[i];
+ if (pSubTree)
+ {
+ pSubTree->parseNodeToStr(aStringPara, rParam);
+
+ // bei den CommaListen zwischen alle Subtrees Commas setzen
+ if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i < (nCount - 1)))
+ aStringPara += String(',');
+ }
+ }
+ aStringPara.EraseTrailingChars(' ');
+ rString += aStringPara;
+ }
+ }
+ else
+ {
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ i != m_aChilds.end();)
+ {
+ const OSQLParseNode* pSubTree = *i;
+ if (pSubTree)
+ {
+ SQLParseNodeParameter aNewParam(rParam);
+
+ // don't replace the field for subqueries
+ if (rParam.xField.is() && SQL_ISRULE(pSubTree,subquery))
+ aNewParam.xField = NULL;
+
+ // if there is a field given we don't display the fieldname, if there are any
+ if (rParam.xField.is() && SQL_ISRULE(pSubTree,column_ref))
+ {
+ sal_Bool bFilter = sal_False;
+ // retrieve the fields name
+ String aFieldName;
+ try
+ {
+ // retrieve the fields name
+ rtl::OUString aString;
+ rParam.xField->getPropertyValue(String::CreateFromAscii("Name")) >>= aString;
+ aFieldName = aString.getStr();
+ }
+ catch ( ... )
+ {
+ }
+
+ const OSQLParseNode* pCol = pSubTree->m_aChilds[pSubTree->count()-1];
+ if ((SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().EqualsIgnoreCaseAscii(aFieldName)) ||
+ pCol->getTokenValue().EqualsIgnoreCaseAscii(aFieldName))
+ bFilter = sal_True;
+
+ // ok we found the field, if the following node is the
+ // comparision operator '=' we filter it as well
+ if (bFilter)
+ {
+ if (SQL_ISRULE(this, comparison_predicate))
+ {
+ ++i;
+ if(i != m_aChilds.end())
+ {
+ pSubTree = *i;
+ if (pSubTree && pSubTree->getNodeType() == SQL_NODE_EQUAL)
+ i++;
+ }
+ }
+ else
+ i++;
+ }
+ else
+ {
+ pSubTree->parseNodeToStr(rString, aNewParam);
+ i++;
+
+ // bei den CommaListen zwischen alle Subtrees Commas setzen
+ if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChilds.end()))
+ rString += String(',');
+ }
+ }
+ else
+ {
+ pSubTree->parseNodeToStr(rString, aNewParam);
+ i++;
+
+ // bei den CommaListen zwischen alle Subtrees Commas setzen
+ if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChilds.end()))
+ {
+ if (SQL_ISRULE(this,value_exp_commalist) && rParam.bPredicate)
+ rString += String(';');
+ else
+ rString += String(',');
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // ein Blatt ist gefunden
+ // Inhalt dem Ausgabestring anfuegen
+ switch (m_eNodeType)
+ {
+ case SQL_NODE_KEYWORD:
+ {
+ if (rString.Len())
+ rString += ' ';
+
+ rString += String::CreateFromAscii(
+ OSQLParser::TokenIDToStr(m_nNodeID, &const_cast<OParseContext&>(rParam.rContext)).GetBuffer());
+ } break;
+ case SQL_NODE_STRING:
+ if (rString.Len())
+ rString += ' ';
+ rString += SetQuotation(m_aNodeValue,String::CreateFromAscii("\'"),String::CreateFromAscii("\'\'"));
+ break;
+ case SQL_NODE_NAME:
+ if (rString.Len())
+ {
+ switch(ByteString::ConvertFromUnicode(rString.GetChar((rString.Len()-1)),RTL_TEXTENCODING_ASCII_US) )
+ {
+ case ' ' :
+ case '.' : break;
+ default :
+ if (!rParam.aCatalogSeparator.Len() || rString.GetChar((sal_uInt32)(rString.Len()-1)) != rParam.aCatalogSeparator.GetChar(0))
+ rString += ' '; break;
+ }
+ }
+ if (rParam.bQuote)
+ {
+ if (rParam.bPredicate)
+ {
+ rString.AppendAscii("[");
+ rString += m_aNodeValue;
+ rString.AppendAscii("]");
+ }
+ else
+ rString += SetQuotation(m_aNodeValue, rParam.aIdentifierQuote.GetChar(0), rParam.aIdentifierQuote.GetChar(0));
+ }
+ else
+ rString += m_aNodeValue;
+ break;
+ case SQL_NODE_ACCESS_DATE:
+ if (rString.Len())
+ rString += ' ';
+ rString += '#';
+ rString += m_aNodeValue;
+ rString += '#';
+ break;
+ case SQL_NODE_INTNUM:
+ case SQL_NODE_APPROXNUM:
+ {
+ String aTmp = m_aNodeValue;
+ if (rParam.bInternational && rParam.bPredicate && rParam.cDecSep != '.')
+ aTmp.SearchAndReplaceAll('.', rParam.cDecSep);
+
+ if (rString.Len())
+ rString += ' ';
+ rString += aTmp;
+
+ } break;
+ // fall through
+ default:
+ if (rString.Len() && m_aNodeValue.GetChar(0) != '.' && m_aNodeValue.GetChar(0) != ':' )
+ {
+ switch( ByteString::ConvertFromUnicode(rString.GetChar(rString.Len()-1),RTL_TEXTENCODING_ASCII_US) )
+ {
+ case ' ' :
+ case '.' : break;
+ default :
+ if (!rParam.aCatalogSeparator.Len() || rString.GetChar(rString.Len()-1) != rParam.aCatalogSeparator.GetChar(0))
+ rString += ' '; break;
+ }
+ }
+ rString += m_aNodeValue;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool OSQLParseNode::addDateValue(String& rString, const SQLParseNodeParameter& rParam) const
+{
+ // special display for date/time values
+ if (rParam.bPredicate && SQL_ISRULE(this,set_fct_spec) && SQL_ISPUNCTUATION(m_aChilds[0],"{"))
+ {
+ const OSQLParseNode* pODBCNode = m_aChilds[1];
+ const OSQLParseNode* pODBCNodeChild = pODBCNode->m_aChilds[0];
+
+ if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && (
+ SQL_ISTOKEN(pODBCNodeChild, D) ||
+ SQL_ISTOKEN(pODBCNodeChild, T) ||
+ SQL_ISTOKEN(pODBCNodeChild, TS) ))
+ {
+ if (rString.Len())
+ rString += ' ';
+ rString += '#';
+ if (SQL_ISTOKEN(pODBCNodeChild, D))
+ rString += convertDateString(rParam, pODBCNode->m_aChilds[1]->getTokenValue());
+ else if (SQL_ISTOKEN(pODBCNodeChild, T))
+ rString += convertTimeString(rParam, pODBCNode->m_aChilds[1]->getTokenValue());
+ else
+ rString += convertDateTimeString(rParam, pODBCNode->m_aChilds[1]->getTokenValue());
+
+ rString += '#';
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::replaceNodeValue(const String& rTableAlias,const String& rColumnName)
+{
+ for (sal_uInt32 i=0;i<count();++i)
+ {
+ if (SQL_ISRULE(this,column_ref) && count() == 1 && getChild(0)->getTokenValue() == rColumnName)
+ {
+ OSQLParseNode * pCol = removeAt((sal_uInt32)0);
+ append(new OSQLParseNode(rTableAlias,SQL_NODE_NAME));
+ append(new OSQLParseNode(String::CreateFromAscii("."),SQL_NODE_PUNCTUATION));
+ append(pCol);
+ }
+ else
+ getChild(i)->replaceNodeValue(rTableAlias,rColumnName);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::tableRangeNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const
+{
+ sal_uInt32 nCount(count());
+ rString += ' ';
+
+ SQLParseNodeParameter aNewParam(rParam);
+ aNewParam.bQuote = sal_False;
+ if (nCount == 4)
+ {
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ m_aChilds[1]->parseNodeToStr(rString, rParam);
+ m_aChilds[2]->parseNodeToStr(rString, aNewParam);
+ m_aChilds[3]->parseNodeToStr(rString, rParam);
+ }
+ else if(nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"("))
+ {
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ m_aChilds[1]->parseNodeToStr(rString, rParam);
+ m_aChilds[2]->parseNodeToStr(rString, rParam);
+ m_aChilds[3]->parseNodeToStr(rString, rParam);
+ m_aChilds[4]->parseNodeToStr(rString, aNewParam);
+ m_aChilds[5]->parseNodeToStr(rString, rParam);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::likeNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const
+{
+ DBG_ASSERT(count() == 5,"count != 5: Prepare for GPF");
+
+ const OSQLParseNode* pEscNode = NULL;
+ const OSQLParseNode* pParaNode = NULL;
+
+ SQLParseNodeParameter aNewParam(rParam);
+ aNewParam.bQuote = sal_True;
+
+ // if there is a field given we don't display the fieldname, if there are any
+ sal_Bool bAddName = sal_True;
+ if (rParam.xField.is())
+ {
+ // retrieve the fields name
+ String aFieldName;
+ try
+ {
+ // retrieve the fields name
+ rtl::OUString aString;
+ rParam.xField->getPropertyValue(String::CreateFromAscii("Name")) >>= aString;
+ aFieldName = aString.getStr();
+ }
+ catch ( ... )
+ {
+ }
+
+ const OSQLParseNode* pCol = m_aChilds[0]->getChild(m_aChilds[0]->count()-1);
+ if ((SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().EqualsIgnoreCaseAscii(aFieldName)) ||
+ pCol->getTokenValue().EqualsIgnoreCaseAscii(aFieldName) )
+ bAddName = sal_False;
+ }
+
+ if (bAddName)
+ m_aChilds[0]->parseNodeToStr(rString, aNewParam);
+
+ m_aChilds[1]->parseNodeToStr(rString, aNewParam);
+ m_aChilds[2]->parseNodeToStr(rString, aNewParam);
+
+ pParaNode = m_aChilds[3];
+ pEscNode = m_aChilds[4];
+
+ if (pParaNode->isToken() && rParam.bInternational)
+ {
+ String aStr = ConvertLikeToken(pParaNode, pEscNode, sal_True);
+ rString += ' ';
+ rString += SetQuotation(aStr,String::CreateFromAscii("\'"),String::CreateFromAscii("\'\'"));
+ }
+ else
+ pParaNode->parseNodeToStr(rString, aNewParam);
+
+ pEscNode->parseNodeToStr(rString, aNewParam);
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::getByRule(OSQLParseNode::Rule eRule) const
+{
+ OSQLParseNode* pRetNode = 0;
+ if (isRule() && OSQLParser::RuleID(eRule) == getRuleID())
+ pRetNode = (OSQLParseNode*)this;
+ else
+ {
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ !pRetNode && i != m_aChilds.end(); i++)
+ pRetNode = (*i)->getByRule(eRule);
+ }
+ return pRetNode;
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode* MakeANDNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf)
+{
+ OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term));
+ pNewNode->append(pLeftLeaf);
+ pNewNode->append(new OSQLParseNode(String::CreateFromAscii("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND));
+ pNewNode->append(pRightLeaf);
+ return pNewNode;
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode* MakeORNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf)
+{
+ OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition));
+ pNewNode->append(pLeftLeaf);
+ pNewNode->append(new OSQLParseNode(String::CreateFromAscii("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR));
+ pNewNode->append(pRightLeaf);
+ return pNewNode;
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::disjunctiveNormalForm(OSQLParseNode*& pSearchCondition)
+{
+ if(!pSearchCondition) // no where condition at entry point
+ return;
+
+ OSQLParseNode::absorptions(pSearchCondition);
+ // '(' search_condition ')'
+ if (SQL_ISRULE(pSearchCondition,boolean_primary))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(1);
+ disjunctiveNormalForm(pLeft);
+ }
+ // search_condition SQL_TOKEN_OR boolean_term
+ else if (SQL_ISRULE(pSearchCondition,search_condition))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ disjunctiveNormalForm(pLeft);
+
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ disjunctiveNormalForm(pRight);
+ }
+ // boolean_term SQL_TOKEN_AND boolean_factor
+ else if (SQL_ISRULE(pSearchCondition,boolean_term))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ disjunctiveNormalForm(pLeft);
+
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ disjunctiveNormalForm(pRight);
+
+ OSQLParseNode* pNewNode = NULL;
+ // '(' search_condition ')'
+ if(pLeft->count() == 3 && SQL_ISRULE(pLeft,boolean_primary) && SQL_ISRULE(pLeft->getChild(1),search_condition))
+ {
+ // and-or tree on left side
+ OSQLParseNode* pOr = pLeft->getChild(1);
+ OSQLParseNode* pNewLeft = NULL;
+ OSQLParseNode* pNewRight = NULL;
+
+ // cut right from parent
+ pSearchCondition->removeAt(2);
+
+ pNewRight = MakeANDNode(pOr->removeAt(2) ,pRight);
+ pNewLeft = MakeANDNode(pOr->removeAt((sal_uInt32)0) ,new OSQLParseNode(*pRight));
+ pNewNode = MakeORNode(pNewLeft,pNewRight);
+ // and append new Node
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+
+ disjunctiveNormalForm(pNewNode);
+ }
+ else if(pRight->count() == 3 && SQL_ISRULE(pRight,boolean_primary) && SQL_ISRULE(pRight->getChild(1),search_condition))
+ {
+ // and-or tree on right side
+ OSQLParseNode* pOr = pRight->getChild(1);
+ OSQLParseNode* pNewLeft = NULL;
+ OSQLParseNode* pNewRight = NULL;
+
+ // cut left from parent
+ pSearchCondition->removeAt((sal_uInt32)0);
+
+ pNewRight = MakeANDNode(pLeft,pOr->removeAt(2));
+ pNewLeft = MakeANDNode(new OSQLParseNode(*pLeft),pOr->removeAt((sal_uInt32)0));
+ pNewNode = MakeORNode(pNewLeft,pNewRight);
+
+ // and append new Node
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+ disjunctiveNormalForm(pNewNode);
+ }
+ else if(SQL_ISRULE(pLeft,boolean_primary) && (!SQL_ISRULE(pLeft->getChild(1),search_condition) || !SQL_ISRULE(pLeft->getChild(1),boolean_term)))
+ pSearchCondition->replace(pLeft, pLeft->removeAt(1));
+ else if(SQL_ISRULE(pRight,boolean_primary) && (!SQL_ISRULE(pRight->getChild(1),search_condition) || !SQL_ISRULE(pRight->getChild(1),boolean_term)))
+ pSearchCondition->replace(pRight, pRight->removeAt(1));
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::negateSearchCondition(OSQLParseNode*& pSearchCondition,sal_Bool bNegate)
+{
+ if(!pSearchCondition) // no where condition at entry point
+ return;
+ OSQLParseNode* pNode = NULL;
+ // '(' search_condition ')'
+ if (pSearchCondition->count() == 3 && SQL_ISRULE(pSearchCondition,boolean_primary))
+ {
+ OSQLParseNode* pRight = pSearchCondition->getChild(1);
+ negateSearchCondition(pRight,bNegate);
+ }
+ // search_condition SQL_TOKEN_OR boolean_term
+ else if (SQL_ISRULE(pSearchCondition,search_condition))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ if(bNegate)
+ {
+ OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term));
+ pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0));
+ pNewNode->append(new OSQLParseNode(String::CreateFromAscii("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND));
+ pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1));
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+ pLeft = pNewNode->getChild(0);
+ pRight = pNewNode->getChild(2);
+ }
+
+ negateSearchCondition(pLeft,bNegate);
+ negateSearchCondition(pRight,bNegate);
+ }
+ // boolean_term SQL_TOKEN_AND boolean_factor
+ else if (SQL_ISRULE(pSearchCondition,boolean_term))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ if(bNegate)
+ {
+ OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition));
+ pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0));
+ pNewNode->append(new OSQLParseNode(String::CreateFromAscii("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR));
+ pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1));
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+ pLeft = pNewNode->getChild(0);
+ pRight = pNewNode->getChild(2);
+ }
+
+ negateSearchCondition(pLeft,bNegate);
+ negateSearchCondition(pRight,bNegate);
+ }
+ // SQL_TOKEN_NOT boolean_test
+ else if (SQL_ISRULE(pSearchCondition,boolean_factor))
+ {
+ OSQLParseNode *pNot = pSearchCondition->removeAt((sal_uInt32)0);
+ delete pNot;
+ OSQLParseNode *pBooleanTest = pSearchCondition->removeAt((sal_uInt32)0);
+ pBooleanTest->setParent(NULL);
+ pSearchCondition->getParent()->replace(pSearchCondition, pBooleanTest);
+ delete pSearchCondition;
+ if (!bNegate)
+ negateSearchCondition(pBooleanTest,sal_True); // negate all deeper values
+ }
+ // row_value_constructor comparison row_value_constructor
+ // row_value_constructor comparison any_all_some subquery
+ else if(bNegate && SQL_ISRULE(pSearchCondition,comparison_predicate) || SQL_ISRULE(pSearchCondition,all_or_any_predicate))
+ {
+ OSQLParseNode* pComparison = pSearchCondition->getChild(1);
+ OSQLParseNode* pNewComparison = NULL;
+ switch(pComparison->getNodeType())
+ {
+ case SQL_NODE_EQUAL:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii("<>"),SQL_NODE_NOTEQUAL,NOTEQUAL);
+ break;
+ case SQL_NODE_LESS:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii(">="),SQL_NODE_GREATEQ,GREATEQ);
+ break;
+ case SQL_NODE_GREAT:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii("<="),SQL_NODE_LESSEQ,LESSEQ);
+ break;
+ case SQL_NODE_LESSEQ:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii(">"),SQL_NODE_GREAT,GREAT);
+ break;
+ case SQL_NODE_GREATEQ:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii("<"),SQL_NODE_LESS,LESS);
+ break;
+ case SQL_NODE_NOTEQUAL:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii("="),SQL_NODE_EQUAL,EQUAL);
+ break;
+ }
+ pSearchCondition->replace(pComparison, pNewComparison);
+ delete pComparison;
+ }
+
+ else if(bNegate && (SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,in_predicate) ||
+ SQL_ISRULE(pSearchCondition,like_predicate) || SQL_ISRULE(pSearchCondition,between_predicate) ||
+ SQL_ISRULE(pSearchCondition,boolean_test) ))
+ {
+ sal_uInt32 nNotPos = 0;
+ // row_value_constructor not SQL_TOKEN_IN in_predicate_value
+ // row_value_constructor not SQL_TOKEN_LIKE num_value_exp opt_escape
+ // row_value_constructor not SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor
+ if(SQL_ISRULE(pSearchCondition,in_predicate) || SQL_ISRULE(pSearchCondition,like_predicate) ||
+ SQL_ISRULE(pSearchCondition,between_predicate))
+ nNotPos = 1;
+ // row_value_constructor SQL_TOKEN_IS not SQL_TOKEN_NULL
+ // boolean_primary SQL_TOKEN_IS not truth_value
+ else if(SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,boolean_test))
+ nNotPos = 2;
+
+ OSQLParseNode* pNot = pSearchCondition->getChild(nNotPos);
+ OSQLParseNode* pNotNot = NULL;
+ if(pNot->isRule())
+ pNotNot = new OSQLParseNode(String::CreateFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
+ else
+ pNotNot = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::not));
+ pSearchCondition->replace(pNot, pNotNot);
+ delete pNot;
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::eraseBraces(OSQLParseNode*& pSearchCondition)
+{
+ if (pSearchCondition && (SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")"))))
+ {
+ OSQLParseNode* pRight = pSearchCondition->getChild(1);
+ absorptions(pRight);
+ // if child is not a or or and tree then delete () around child
+ if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) ||
+ SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || // and can always stand without ()
+ (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition)))
+ {
+ OSQLParseNode* pNode = pSearchCondition->removeAt(1);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::absorptions(OSQLParseNode*& pSearchCondition)
+{
+ if(!pSearchCondition) // no where condition at entry point
+ return;
+
+ eraseBraces(pSearchCondition);
+
+ if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ absorptions(pLeft);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ absorptions(pRight);
+ }
+
+ // a and a || a or a
+ OSQLParseNode* pNewNode = NULL;
+ if(( SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
+ && *pSearchCondition->getChild(0) == *pSearchCondition->getChild(2))
+ {
+ pNewNode = pSearchCondition->removeAt((sal_uInt32)0);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ // (a or b) and a
+ else if(SQL_ISRULE(pSearchCondition,boolean_term) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_primary) &&
+ SQL_ISRULE(pSearchCondition->getChild(0)->getChild(1),search_condition) &&
+ *pSearchCondition->getChild(0)->getChild(1)->getChild(0) == *pSearchCondition->getChild(2))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt(2));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ // a and ( a or b)
+ else if(SQL_ISRULE(pSearchCondition,boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_primary) &&
+ SQL_ISRULE(pSearchCondition->getChild(2)->getChild(1),search_condition))
+
+ {
+ if(*pSearchCondition->getChild(2)->getChild(1)->getChild(0) == *pSearchCondition->getChild(0))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ else if(*pSearchCondition->getChild(2)->getChild(1)->getChild(2) == *pSearchCondition->getChild(0))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ }
+ // a or a and b || a or b and a
+ else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term))
+ {
+ if(*pSearchCondition->getChild(2)->getChild(0) == *pSearchCondition->getChild(0))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ else if(*pSearchCondition->getChild(2)->getChild(2) == *pSearchCondition->getChild(0))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ }
+ // a and b or a || b and a or a
+ else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term))
+ {
+ if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ }
+ eraseBraces(pSearchCondition);
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::compress(OSQLParseNode *&pSearchCondition)
+{
+ if(!pSearchCondition) // no where condition at entry point
+ return;
+
+ OSQLParseNode::eraseBraces(pSearchCondition);
+
+ if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ compress(pLeft);
+
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ compress(pRight);
+ }
+ else if( SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")))
+ {
+ OSQLParseNode* pRight = pSearchCondition->getChild(1);
+ compress(pRight);
+ // if child is not a or or and tree then delete () around child
+ if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) ||
+ (SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) && SQL_ISRULE(pSearchCondition->getParent(),boolean_term)) ||
+ (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition)))
+ {
+ OSQLParseNode* pNode = pSearchCondition->removeAt(1);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ }
+
+ OSQLParseNode* pNewNode = NULL;
+ // or with two and trees where one element of the and trees are equal
+ if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term))
+ {
+ if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(0))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2);
+ OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
+
+ OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION));
+ pNewRule->append(pNode);
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION));
+
+ OSQLParseNode::eraseBraces(pLeft);
+ OSQLParseNode::eraseBraces(pRight);
+
+ pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(0))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2);
+ OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
+
+ OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION));
+ pNewRule->append(pNode);
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION));
+
+ OSQLParseNode::eraseBraces(pLeft);
+ OSQLParseNode::eraseBraces(pRight);
+
+ pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ else if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(2))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0);
+ OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
+
+ OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION));
+ pNewRule->append(pNode);
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION));
+
+ OSQLParseNode::eraseBraces(pLeft);
+ OSQLParseNode::eraseBraces(pRight);
+
+ pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(2))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0);
+ OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
+
+ OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION));
+ pNewRule->append(pNode);
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION));
+
+ OSQLParseNode::eraseBraces(pLeft);
+ OSQLParseNode::eraseBraces(pRight);
+
+ pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::showParseTree(String& rString, sal_uInt32 nLevel)
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+
+ if (!isToken())
+ {
+ for (sal_uInt32 j=0; j<nLevel; j++) {rString.AppendAscii("\t");};
+ // Regelnamen als rule: ...
+ rString.AppendAscii("RULE_ID:\t ");
+ rString += (String) getRuleID();
+ rString.AppendAscii("(");
+ rString += OSQLParser::RuleIDToStr(getRuleID());
+ rString.AppendAscii(")");
+ rString.AppendAscii("\n");
+
+ // einmal auswerten wieviel Subtrees dieser Knoten besitzt
+ sal_uInt32 nStop = count();
+ // hol dir den ersten Subtree
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ i != m_aChilds.end(); i++)
+ (*i)->showParseTree(rString, nLevel+1);
+ }
+ else {
+ // ein Token gefunden
+ // tabs fuer das Einruecken entsprechend nLevel
+ for (sal_uInt32 j=0; j<nLevel; j++) {rString.AppendAscii("\t");};
+
+ switch (m_eNodeType) {
+
+ case SQL_NODE_KEYWORD:
+ {rString.AppendAscii("SQL_KEYWORD:\t");
+ rString += String::CreateFromAscii(OSQLParser::TokenIDToStr(getTokenID()).GetBuffer());
+ rString.AppendAscii("\n");
+ break;}
+
+ case SQL_NODE_COMPARISON:
+ {rString.AppendAscii("SQL_COMPARISON:\t");
+ rString += m_aNodeValue; // haenge Nodevalue an
+ rString.AppendAscii("\n"); // und beginne neu Zeile
+ break;}
+
+ case SQL_NODE_NAME:
+ {rString.AppendAscii("SQL_NAME:\t");
+ rString.AppendAscii("\"");
+ rString += m_aNodeValue;
+ rString.AppendAscii("\"");
+ rString.AppendAscii("\n");
+ break;}
+
+ case SQL_NODE_STRING:
+ {rString .AppendAscii("SQL_STRING:\t'");
+ rString += m_aNodeValue;
+ rString .AppendAscii("'\n");
+ break;}
+
+ case SQL_NODE_INTNUM:
+ {rString .AppendAscii("SQL_INTNUM:\t");
+ rString += m_aNodeValue;
+ rString .AppendAscii("\n");
+ break;}
+
+ case SQL_NODE_APPROXNUM:
+ {rString .AppendAscii("SQL_APPROXNUM:\t");
+ rString += m_aNodeValue;
+ rString .AppendAscii("\n");
+ break;}
+
+ case SQL_NODE_PUNCTUATION:
+ {rString .AppendAscii("SQL_PUNCTUATION:\t");
+ rString += m_aNodeValue; // haenge Nodevalue an
+ rString .AppendAscii("\n"); // und beginne neu Zeile
+ break;}
+
+ case SQL_NODE_AMMSC:
+ {rString .AppendAscii("SQL_AMMSC:\t");
+ rString += m_aNodeValue; // haenge Nodevalue an
+ rString .AppendAscii("\n"); // und beginne neu Zeile
+ break;}
+
+ default:
+ DBG_ERROR("OSQLParser::ShowParseTree: unzulaessiger NodeType");
+ }
+ };
+}
+
+// Insert-Methoden
+//-----------------------------------------------------------------------------
+void OSQLParseNode::insert(sal_uInt32 nPos, OSQLParseNode* pNewSubTree)
+{
+ DBG_ASSERT(pNewSubTree != NULL, "OSQLParseNode: ungueltiger NewSubTree");
+ DBG_ASSERT(pNewSubTree->getParent() == NULL, "OSQLParseNode: Knoten ist kein Waise");
+
+ // stelle Verbindung zum getParent her:
+ pNewSubTree->setParent( this );
+ m_aChilds.insert(m_aChilds.begin() + nPos);
+}
+
+// removeAt-Methoden
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::removeAt(sal_uInt32 nPos)
+{
+ ::std::vector<OSQLParseNode*>::iterator aPos(m_aChilds.begin() + nPos);
+ OSQLParseNode* pNode = *aPos;
+
+ // setze den getParent des removeten auf NULL
+ pNode->setParent( NULL );
+
+ m_aChilds.erase(aPos);
+ return pNode;
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::remove(OSQLParseNode* pSubTree)
+{
+ DBG_ASSERT(pSubTree != NULL, "OSQLParseNode: ungueltiger SubTree");
+ ::std::vector<OSQLParseNode*>::iterator aPos = ::std::find(m_aChilds.begin(), m_aChilds.end(), pSubTree);
+ if (aPos != m_aChilds.end())
+ {
+ // setze den getParent des removeten auf NULL
+ pSubTree->setParent( NULL );
+ m_aChilds.erase(aPos);
+ return pSubTree;
+ }
+ else
+ return NULL;
+}
+
+// Replace-Methoden
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::replaceAt(sal_uInt32 nPos, OSQLParseNode* pNewSubNode)
+{
+ DBG_ASSERT(pNewSubNode != NULL, "OSQLParseNode: invalid nodes");
+ DBG_ASSERT(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent");
+ DBG_ASSERT(nPos < m_aChilds.size(), "OSQLParseNode: invalid position");
+ DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewSubNode) == m_aChilds.end(),
+ "OSQLParseNode::Replace() Node already element of parent");
+
+ OSQLParseNode* pOldSubNode = m_aChilds[nPos];
+
+ // stelle Verbindung zum getParent her:
+ pNewSubNode->setParent( this );
+ pOldSubNode->setParent( NULL );
+
+ m_aChilds[nPos] = pNewSubNode;
+ return pOldSubNode;
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::replace (OSQLParseNode* pOldSubNode, OSQLParseNode* pNewSubNode )
+{
+ DBG_ASSERT(pOldSubNode != NULL && pNewSubNode != NULL, "OSQLParseNode: invalid nodes");
+ DBG_ASSERT(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent");
+ DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pOldSubNode) != m_aChilds.end(),
+ "OSQLParseNode::Replace() Node not element of parent");
+ DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewSubNode) == m_aChilds.end(),
+ "OSQLParseNode::Replace() Node already element of parent");
+
+ pOldSubNode->setParent( NULL );
+ pNewSubNode->setParent( this );
+ ::std::replace(m_aChilds.begin(), m_aChilds.end(), pOldSubNode, pNewSubNode);
+ return pOldSubNode;
+}
+
+