libgda r3174 - in trunk: . doc/C po providers/firebird
- From: vivien svn gnome org
- To: svn-commits-list gnome org
- Subject: libgda r3174 - in trunk: . doc/C po providers/firebird
- Date: Sat, 5 Jul 2008 15:50:46 +0000 (UTC)
Author: vivien
Date: Sat Jul 5 15:50:46 2008
New Revision: 3174
URL: http://svn.gnome.org/viewvc/libgda?rev=3174&view=rev
Log:
2008-07-05 Vivien Malerba <malerba gnome-db org>
* doc/C: doc. updates
* providers/firebird: added forgotten files
* po/POTFILES.in: added missing files
* NEWS: news for version
Added:
trunk/providers/firebird/firebird_specs_create_table.xml.in
trunk/providers/firebird/gda-firebird-ddl.c
trunk/providers/firebird/gda-firebird-ddl.h
trunk/providers/firebird/gda-firebird-meta.c
trunk/providers/firebird/gda-firebird-meta.h
trunk/providers/firebird/gda-firebird-parser.c
trunk/providers/firebird/gda-firebird-parser.h
trunk/providers/firebird/gda-firebird-pstmt.c
trunk/providers/firebird/gda-firebird-pstmt.h
trunk/providers/firebird/gda-firebird-util.c
trunk/providers/firebird/gda-firebird-util.h
trunk/providers/firebird/gda-firebird.h
trunk/providers/firebird/gen_def.c
trunk/providers/firebird/parser.y
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/doc/C/i_s_doc.xml
trunk/doc/C/libgda-4.0-docs.sgml
trunk/doc/C/limitations.xml
trunk/po/POTFILES.in
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Sat Jul 5 15:50:46 2008
@@ -1,3 +1,40 @@
+libgda 3.99.3, 2008-07-05
+
+ This version includes:
+ - lots of bug fixed, memory leaks fixes and general performance improvements
+ (Murray Cumming, Daniel Espinosa, Cygwin Ports maintainer, Phil Longstaff,
+ Carlos Savoretti, Johannes Schmid, Yuriy Penkin, Vivien Malerba)
+ - MySQL support starting to work again (Carlos Savoretti)
+ - documentation improvements
+ - added function to compute INSERT, UPDATE and DELETE statements from a SELECT
+ statement, to be able to have writable data models after a SELECT execution
+ - API changes for easier understanding and usage (gda_init() for example)
+ - added the possibility to check the validity of a statement using the database's
+ associated meta data
+ - improvements to the convenience functions when creating or dropping a table (Daniel Espinosa)
+ - new data model comparator object
+ - make the SQL parser(s) correctly handle SQL identifiers enclosed in double quotes
+ - more checks
+ - new function to the xslt extension libgda-xslt (Pawel Cesar)
+ - new SQL code completion feature (incorporated into the gda-sql tool)
+ - gda-sql tool improvements (SQL completion, command line parsing)
+ - reworked the authentication mechanism as some database don't require a username/password
+ - allow the [<username>[:<password>] ]<DSN> format of string when opening a connection using
+ a predefined data source, or [<provider>://][<username>[:<password>] ]<connection string>
+ when opening a connection without a predefined data source
+ - now internally use SQLite 3.5.9
+ - use GIO instead of GnomeVFS if found
+ - preliminary MacOS X support, and better support for cross compilation
+ - better support for thread safe support
+ - new distributed transaction support
+ - added speficications to create a .MSI file as a Windows installer
+ - bug fixes: #524837, #525601, #525877, #526748, #527892, #527002, #534805, #536418,
+ #536971, #537558, #537117
+ - Translations:
+ - es (Jorge Gonzalez)
+ - pt (Duarte Loreto)
+ - oc (Yannig Marchegay)
+
libgda 3.99.2, 2008-03-24
This version:
Modified: trunk/doc/C/i_s_doc.xml
==============================================================================
--- trunk/doc/C/i_s_doc.xml (original)
+++ trunk/doc/C/i_s_doc.xml Sat Jul 5 15:50:46 2008
@@ -1,5 +1,5 @@
<sect2>
-<!--File generated by the tools/information-schema-doc program from the
+ <!--File generated by the tools/information-schema-doc program from the
libgda/information-schema.xml file,
do not modify-->
<title>Individual table description</title>
@@ -219,7 +219,7 @@
<sect3 id="is:_key_column_usage">
<title>_key_column_usage table</title>
<para>List of primary key constraints and the name of the tables' columns involved</para>
- <para>The following table describes the columns:<informaltable frame="all"><tgroup cols="5" colsep="1" rowsep="1" align="justify"><thead><row><entry>Column name</entry><entry>Type</entry><entry>Key</entry><entry>Can be NULL</entry><entry>description</entry></row></thead><tbody><row><entry>table_catalog</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>table_schema</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>table_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>constraint_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>column_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>ordinal_position</entry><entry>gint</entry><entry>Yes</entry><entry>No</entry><entry></entry></row></tbody></tgroup></informaltable></para>
+ <para>The following table describes the columns:<informaltable frame="all"><tgroup cols="5" colsep="1" rowsep="1" align="justify"><thead><row><entry>Column name</entry><entry>Type</entry><entry>Key</entry><entry>Can be NULL</entry><entry>description</entry></row></thead><tbody><row><entry>table_catalog</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>table_schema</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>table_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>constraint_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>column_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>ordinal_position</entry><entry>gint</entry><entry>Yes</entry><entry>No</entry><entry>Ordinal position of the column within the constraint key (count
starts at 1)</entry></row></tbody></tgroup></informaltable></para>
<para>
<itemizedlist>
<listitem>
Modified: trunk/doc/C/libgda-4.0-docs.sgml
==============================================================================
--- trunk/doc/C/libgda-4.0-docs.sgml (original)
+++ trunk/doc/C/libgda-4.0-docs.sgml Sat Jul 5 15:50:46 2008
@@ -2,7 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY nbsp " ">
-<!ENTITY LIBGDA "<application>libgda</application>">
+<!ENTITY LIBGDA "<application>Libgda</application>">
<!ENTITY GNOMEDB "<application>GNOME-DB</application>">
<!ENTITY igalia '<emphasis><ulink url="http://www.igalia.com">Igalia, S.L.</ulink></emphasis>'>
<!ENTITY xobas '<emphasis><ulink url="http://www.xobas.com">Xobas Software</ulink></emphasis>'>
@@ -318,6 +318,10 @@
<listitem>
<para>Support for virtual connections, see the <link linkend="virtual_connection">Virtual connections chapter</link></para>
</listitem>
+ <listitem>
+ <para>Partially thread-safe, see <link linkend="threads">the threads limitation</link> for
+ more details</para>
+ </listitem>
</itemizedlist>
</para>
<para>
Modified: trunk/doc/C/limitations.xml
==============================================================================
--- trunk/doc/C/limitations.xml (original)
+++ trunk/doc/C/limitations.xml Sat Jul 5 15:50:46 2008
@@ -1,6 +1,20 @@
<chapter id="limitations">
<title>Limitations</title>
+ <sect1 id="limitations_global"><title>Global limitations</title>
+ <para>
+ &LIBGDA;'s global limitations are:
+ <sect2 id="threads"><title>Multi threading</title>
+ <para>&LIBGDA; is not thread safe. However it supports working with threads as long as
+ any object created by the API is used by one single thread (that is there is no
+ situation when two threads try to acces the same object at the same time).
+ </para>
+ <para>For example it is safe to start a thread and in that thread create a connection
+ which is only used in that thread.</para>
+ </sect2>
+ </para>
+ </sect1>
+
<sect1 id="limitations_mysql"><title>For MySQL</title>
<para>
The following limitations apply to MySQL databases accessed via Libgda: none.
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Sat Jul 5 15:50:46 2008
@@ -67,6 +67,7 @@
providers/mdb/libmain.c
providers/mdb/mdb_specs_dsn.xml.in
providers/mysql/gda-mysql-ddl.c
+providers/mysql/gda-mysql-meta.c
providers/mysql/gda-mysql-provider.c
providers/mysql/gda-mysql-recordset.c
providers/mysql/gda-mysql-util.c
Added: trunk/providers/firebird/firebird_specs_create_table.xml.in
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/firebird_specs_create_table.xml.in Sat Jul 5 15:50:46 2008
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<serv_op>
+ <parameters id="TABLE_DEF_P" _name="Table's description">
+ <parameter id="TABLE_NAME" _name="Name" _descr="Table's name" gdatype="gchararray" nullok="FALSE">
+ <gda_value>table_name</gda_value>
+ </parameter>
+ </parameters>
+
+ <!-- list of fields -->
+ <gda_array id="FIELDS_A" _name="Table's columns">
+ <gda_array_field id="COLUMN_NAME" _name="Field name" gdatype="gchararray" nullok="FALSE"/>
+ <gda_array_field id="COLUMN_TYPE" _name="Data type" gdatype="gchararray" hint="datatype" nullok="FALSE"/>
+ <gda_array_field id="COLUMN_NNUL" _name="Not NULL" gdatype="gboolean"/>
+ <gda_array_field id="COLUMN_UNIQUE" _name="Unique" gdatype="gboolean"/>
+ <gda_array_field id="COLUMN_PKEY" _name="Primary key" gdatype="gboolean"/>
+ <gda_array_field id="COLUMN_DEFAULT" _name="Default" _descr="Default value" gdatype="gchararray"/>
+ <gda_array_field id="COLUMN_CHECK" _name="Check" _descr="Check constraint" gdatype="gchararray"/>
+ <gda_array_data>
+ <gda_array_row>
+ <gda_value>id</gda_value>
+ <gda_value>integer</gda_value>
+ <gda_value>TRUE</gda_value>
+ <gda_value>TRUE</gda_value>
+ <gda_value>TRUE</gda_value>
+ <gda_value></gda_value>
+ <gda_value></gda_value>
+ </gda_array_row>
+ </gda_array_data>
+ </gda_array>
+
+ <!-- other table constraints -->
+ <sequence id="TABLE_CONSTRAINTS_S" _name="Global constraints">
+ <parameter id="CONSTRAINT_STRING" name="Constraint" gdatype="gchararray">
+ <gda_value>CHECK (column > 0)</gda_value>
+ </parameter>
+ </sequence>
+</serv_op>
Added: trunk/providers/firebird/gda-firebird-ddl.c
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-ddl.c Sat Jul 5 15:50:46 2008
@@ -0,0 +1,144 @@
+/* GDA Firebird Provider
+ * Copyright (C) 2008 The GNOME Foundation
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib/gi18n-lib.h>
+#include <libgda/libgda.h>
+#include "gda-firebird-ddl.h"
+
+gchar *
+gda_firebird_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gboolean allok = TRUE;
+ gboolean hasfields = FALSE;
+ gint nrows;
+ gint i;
+ gboolean first;
+ GSList *pkfields = NULL; /* list of GValue* composing the pkey */
+ gint nbpkfields = 0;
+ gchar *sql = NULL;
+
+ /* CREATE TABLE */
+ string = g_string_new ("CREATE TABLE ");
+
+ value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+ g_string_append (string, " (");
+
+ /* FIELDS */
+ if (allok) {
+ GdaServerOperationNode *node;
+
+ node = gda_server_operation_get_node_info (op, "/FIELDS_A");
+ g_assert (node);
+
+ /* finding if there is a composed primary key */
+ nrows = gda_data_model_get_n_rows (node->model);
+ for (i = 0; i < nrows; i++) {
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ pkfields = g_slist_append (pkfields,
+ (GValue *) gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i));
+ }
+ nbpkfields = g_slist_length (pkfields);
+
+ /* manually defined fields */
+ first = TRUE;
+ for (i = 0; i < nrows; i++) {
+ hasfields = TRUE;
+ if (first)
+ first = FALSE;
+ else
+ g_string_append (string, ", ");
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
+ g_string_append (string, g_value_get_string (value));
+ g_string_append_c (string, ' ');
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_DEFAULT/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append (string, " DEFAULT ");
+ g_string_append (string, str);
+ }
+ }
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NNUL/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " NOT NULL");
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_UNIQUE/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " UNIQUE");
+
+ if (nbpkfields == 1) {
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " PRIMARY KEY");
+ }
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CHECK/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append (string, " CHECK (");
+ g_string_append (string, str);
+ g_string_append_c (string, ')');
+ }
+ }
+ }
+ }
+
+ /* composed primary key */
+ if (nbpkfields > 1) {
+ GSList *list = pkfields;
+
+ g_string_append (string, ", PRIMARY KEY (");
+ while (list) {
+ if (list != pkfields)
+ g_string_append (string, ", ");
+ g_string_append (string, g_value_get_string ((GValue*) list->data));
+ list = list->next;
+ }
+ g_string_append_c (string, ')');
+ }
+
+ g_string_append (string, ")");
+
+ if (!hasfields) {
+ allok = FALSE;
+ g_set_error (error, 0, 0, _("Table to create must have at least one row"));
+ }
+ g_slist_free (pkfields);
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
Added: trunk/providers/firebird/gda-firebird-ddl.h
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-ddl.h Sat Jul 5 15:50:46 2008
@@ -0,0 +1,34 @@
+/* GDA Firebird provider
+ * Copyright (C) 2008 The GNOME Foundation
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __GDA_FIREBIRD_DDL_H__
+#define __GDA_FIREBIRD_DDL_H__
+
+#include <libgda/gda-server-provider.h>
+
+G_BEGIN_DECLS
+
+gchar *gda_firebird_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error);
+G_END_DECLS
+
+#endif
+
Added: trunk/providers/firebird/gda-firebird-meta.c
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-meta.c Sat Jul 5 15:50:46 2008
@@ -0,0 +1,488 @@
+/* GDA firebird provider
+ * Copyright (C) 2008 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * TO_ADD: your name and email
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include "gda-firebird.h"
+#include "gda-firebird-meta.h"
+#include "gda-firebird-provider.h"
+#include <libgda/gda-meta-store.h>
+#include <libgda/sql-parser/gda-sql-parser.h>
+#include <glib/gi18n-lib.h>
+#include <libgda/gda-server-provider-extra.h>
+#include <libgda/gda-connection-private.h>
+#include <libgda/gda-data-model-array.h>
+#include <libgda/gda-set.h>
+#include <libgda/gda-holder.h>
+
+static gboolean append_a_row (GdaDataModel *to_model, GError **error, gint nb, ...);
+
+/*
+ * predefined statements' IDs
+ */
+typedef enum {
+ I_STMT_1,
+} InternalStatementItem;
+
+
+/*
+ * predefined statements' SQL
+ */
+static gchar *internal_sql[] = {
+ "SQL for I_STMT_1"
+};
+
+/*
+ * global static values, and
+ * predefined statements' GdaStatement, all initialized in _gda_postgres_provider_meta_init()
+ */
+static GdaStatement **internal_stmt;
+static GdaSqlParser *internal_parser = NULL;
+static GdaSet *i_set;
+
+/* TO_ADD: other static values */
+
+
+/*
+ * Meta initialization
+ */
+void
+_gda_firebird_provider_meta_init (GdaServerProvider *provider)
+{
+ static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
+ InternalStatementItem i;
+
+ g_static_mutex_lock (&init_mutex);
+
+ internal_parser = gda_server_provider_internal_get_parser (provider);
+ internal_stmt = g_new0 (GdaStatement *, sizeof (internal_sql) / sizeof (gchar*));
+ for (i = I_STMT_1; i < sizeof (internal_sql) / sizeof (gchar*); i++) {
+ internal_stmt[i] = gda_sql_parser_parse_string (internal_parser, internal_sql[i], NULL, NULL);
+ if (!internal_stmt[i])
+ g_error ("Could not parse internal statement: %s\n", internal_sql[i]);
+ }
+
+ /* initialize static values here */
+ i_set = gda_set_new_inline (4, "cat", G_TYPE_STRING, "",
+ "name", G_TYPE_STRING, "",
+ "schema", G_TYPE_STRING, "",
+ "name2", G_TYPE_STRING, "");
+ g_static_mutex_unlock (&init_mutex);
+}
+
+gboolean
+_gda_firebird_meta__info (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ GdaDataModel *model;
+ gboolean retval;
+
+ TO_IMPLEMENT;
+ /* fill in @model, with something like:
+ * model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_1], NULL,
+ * error);
+ */
+ if (!model)
+ return FALSE;
+ retval = gda_meta_store_modify_with_context (store, context, model, error);
+ g_object_unref (model);
+
+ return retval;
+}
+
+gboolean
+_gda_firebird_meta__btypes (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__udt (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_udt (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *udt_catalog, const GValue *udt_schema)
+{
+ GdaDataModel *model;
+ gboolean retval = TRUE;
+
+ /* set internal holder's values from the arguments */
+ gda_holder_set_value (gda_set_get_holder (i_set, "cat"), udt_catalog);
+ gda_holder_set_value (gda_set_get_holder (i_set, "schema"), udt_schema);
+
+ TO_IMPLEMENT;
+ /* fill in @model, with something like:
+ * model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_UDT], i_set, error);
+ */
+ if (!model)
+ return FALSE;
+ retval = gda_meta_store_modify_with_context (store, context, model, error);
+ g_object_unref (model);
+
+ return retval;
+}
+
+
+gboolean
+_gda_firebird_meta__udt_cols (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_udt_cols (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *udt_catalog, const GValue *udt_schema, const GValue *udt_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__enums (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_enums (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *udt_catalog, const GValue *udt_schema, const GValue *udt_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+
+gboolean
+_gda_firebird_meta__domains (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_domains (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *domain_catalog, const GValue *domain_schema)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__constraints_dom (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_constraints_dom (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *domain_catalog, const GValue *domain_schema,
+ const GValue *domain_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__el_types (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_el_types (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *specific_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__collations (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_collations (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *collation_catalog, const GValue *collation_schema,
+ const GValue *collation_name_n)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__character_sets (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_character_sets (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *chset_catalog, const GValue *chset_schema,
+ const GValue *chset_name_n)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__schemata (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_schemata (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *catalog_name, const GValue *schema_name_n)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__tables_views (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_tables_views (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name_n)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__view_cols (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_view_cols (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *view_catalog, const GValue *view_schema,
+ const GValue *view_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__constraints_tab (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_constraints_tab (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name, const GValue *constraint_name_n)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__constraints_ref (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_constraints_ref (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__key_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_key_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name, const GValue *constraint_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__check_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_check_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name, const GValue *constraint_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__triggers (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_triggers (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__routines (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_routines (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *routine_catalog, const GValue *routine_schema,
+ const GValue *routine_name_n)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__routine_col (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_routine_col (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *rout_catalog, const GValue *rout_schema,
+ const GValue *rout_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta__routine_par (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
+
+gboolean
+_gda_firebird_meta_routine_par (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *rout_catalog, const GValue *rout_schema,
+ const GValue *rout_name)
+{
+ TO_IMPLEMENT;
+ return TRUE;
+}
Added: trunk/providers/firebird/gda-firebird-meta.h
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-meta.h Sat Jul 5 15:50:46 2008
@@ -0,0 +1,197 @@
+/* GDA firebird provider
+ * Copyright (C) 2008 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * TO_ADD: your name and email
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __GDA_FIREBIRD_META_H__
+#define __GDA_FIREBIRD_META_H__
+
+#include <libgda/gda-server-provider.h>
+
+G_BEGIN_DECLS
+
+void _gda_firebird_provider_meta_init (GdaServerProvider *provider);
+
+/* _information_schema_catalog_name */
+gboolean _gda_firebird_meta__info (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+
+/* _builtin_data_types */
+gboolean _gda_firebird_meta__btypes (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+
+/* _udt */
+gboolean _gda_firebird_meta__udt (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_udt (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *udt_catalog, const GValue *udt_schema);
+
+/* _udt_columns */
+gboolean _gda_firebird_meta__udt_cols (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_udt_cols (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *udt_catalog, const GValue *udt_schema, const GValue *udt_name);
+
+/* _enums */
+gboolean _gda_firebird_meta__enums (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_enums (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *udt_catalog, const GValue *udt_schema, const GValue *udt_name);
+
+/* _domains */
+gboolean _gda_firebird_meta__domains (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_domains (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *domain_catalog, const GValue *domain_schema);
+
+/* _domain_constraints */
+gboolean _gda_firebird_meta__constraints_dom (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_constraints_dom (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *domain_catalog, const GValue *domain_schema,
+ const GValue *domain_name);
+
+/* _element_types */
+gboolean _gda_firebird_meta__el_types (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_el_types (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *specific_name);
+
+/* _collations */
+gboolean _gda_firebird_meta__collations (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_collations (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *collation_catalog, const GValue *collation_schema,
+ const GValue *collation_name_n);
+
+/* _character_sets */
+gboolean _gda_firebird_meta__character_sets (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_character_sets (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *chset_catalog, const GValue *chset_schema,
+ const GValue *chset_name_n);
+
+/* _schemata */
+gboolean _gda_firebird_meta__schemata (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_schemata (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *catalog_name, const GValue *schema_name_n);
+
+/* _tables or _views */
+gboolean _gda_firebird_meta__tables_views (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_tables_views (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name_n);
+
+/* _columns */
+gboolean _gda_firebird_meta__columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name);
+
+/* _view_column_usage */
+gboolean _gda_firebird_meta__view_cols (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_view_cols (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *view_catalog, const GValue *view_schema,
+ const GValue *view_name);
+
+/* _table_constraints */
+gboolean _gda_firebird_meta__constraints_tab (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_constraints_tab (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name, const GValue *constraint_name_n);
+
+/* _referential_constraints */
+gboolean _gda_firebird_meta__constraints_ref (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_constraints_ref (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name);
+
+/* _key_column_usage */
+gboolean _gda_firebird_meta__key_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_key_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name, const GValue *constraint_name);
+
+/* _check_column_usage */
+gboolean _gda_firebird_meta__check_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_check_columns (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name, const GValue *constraint_name);
+
+/* _triggers */
+gboolean _gda_firebird_meta__triggers (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_triggers (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema,
+ const GValue *table_name);
+
+/* _routines */
+gboolean _gda_firebird_meta__routines (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_routines (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *routine_catalog, const GValue *routine_schema,
+ const GValue *routine_name_n);
+
+/* _routine_columns */
+gboolean _gda_firebird_meta__routine_col (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_routine_col (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *rout_catalog, const GValue *rout_schema,
+ const GValue *rout_name);
+
+/* _parameters */
+gboolean _gda_firebird_meta__routine_par (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error);
+gboolean _gda_firebird_meta_routine_par (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *rout_catalog, const GValue *rout_schema,
+ const GValue *rout_name);
+
+
+G_END_DECLS
+
+#endif
+
Added: trunk/providers/firebird/gda-firebird-parser.c
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-parser.c Sat Jul 5 15:50:46 2008
@@ -0,0 +1,84 @@
+/* GDA Firebird provider
+ *
+ * Copyright (C) 2008 The GNOME Foundation
+ *
+ * AUTHORS:
+ * TO_ADD: your name and email
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gda-firebird-parser.h"
+#include "firebird_token_types.h"
+#include <string.h>
+
+/*
+ * Main static functions
+ */
+static void gda_firebird_parser_class_init (GdaFirebirdParserClass *klass);
+static void gda_firebird_parser_init (GdaFirebirdParser *stmt);
+
+GType
+gda_firebird_parser_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static GStaticMutex registering = G_STATIC_MUTEX_INIT;
+ static const GTypeInfo info = {
+ sizeof (GdaFirebirdParserClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gda_firebird_parser_class_init,
+ NULL,
+ NULL,
+ sizeof (GdaFirebirdParser),
+ 0,
+ (GInstanceInitFunc) gda_firebird_parser_init
+ };
+
+ g_static_mutex_lock (®istering);
+ if (type == 0)
+ type = g_type_register_static (GDA_TYPE_SQL_PARSER, "GdaFirebirdParser", &info, 0);
+ g_static_mutex_unlock (®istering);
+ }
+ return type;
+}
+
+/*
+ * The interface to the LEMON-generated parser
+ */
+void *gda_lemon_firebird_parserAlloc (void*(*)(size_t));
+void gda_lemon_firebird_parserFree (void*, void(*)(void*));
+void gda_lemon_firebird_parserTrace (void*, char *);
+void gda_lemon_firebird_parser (void*, int, GValue *, GdaSqlParserIface *);
+
+static void
+gda_firebird_parser_class_init (GdaFirebirdParserClass * klass)
+{
+ GdaSqlParserClass *pclass = GDA_SQL_PARSER_CLASS (klass);
+
+ pclass->parser_alloc = gda_lemon_firebird_parserAlloc;
+ pclass->parser_free = gda_lemon_firebird_parserFree;
+ pclass->parser_trace = gda_lemon_firebird_parserTrace;
+ pclass->parser_parse = gda_lemon_firebird_parser;
+ pclass->parser_tokens_trans = firebird_parser_tokens;
+}
+
+static void
+gda_firebird_parser_init (GdaFirebirdParser *parser)
+{
+}
Added: trunk/providers/firebird/gda-firebird-parser.h
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-parser.h Sat Jul 5 15:50:46 2008
@@ -0,0 +1,59 @@
+/* GDA Firebird provider
+ *
+ * Copyright (C) 2008 The GNOME Foundation
+ *
+ * AUTHORS:
+ * TO_ADD: your name and email
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GDA_FIREBIRD_PARSER_H_
+#define __GDA_FIREBIRD_PARSER_H_
+
+#include <sql-parser/gda-sql-parser.h>
+
+G_BEGIN_DECLS
+
+#define GDA_TYPE_FIREBIRD_PARSER (gda_firebird_parser_get_type())
+#define GDA_FIREBIRD_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GDA_TYPE_FIREBIRD_PARSER, GdaFirebirdParser))
+#define GDA_FIREBIRD_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (klass, GDA_TYPE_FIREBIRD_PARSER, GdaFirebirdParserClass))
+#define GDA_IS_FIREBIRD_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GDA_TYPE_FIREBIRD_PARSER))
+#define GDA_IS_FIREBIRD_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDA_TYPE_FIREBIRD_PARSER))
+
+typedef struct _GdaFirebirdParser GdaFirebirdParser;
+typedef struct _GdaFirebirdParserClass GdaFirebirdParserClass;
+typedef struct _GdaFirebirdParserPrivate GdaFirebirdParserPrivate;
+
+/* struct for the object's data */
+struct _GdaFirebirdParser
+{
+ GdaSqlParser object;
+ GdaFirebirdParserPrivate *priv;
+};
+
+/* struct for the object's class */
+struct _GdaFirebirdParserClass
+{
+ GdaSqlParserClass parent_class;
+};
+
+GType gda_firebird_parser_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif
Added: trunk/providers/firebird/gda-firebird-pstmt.c
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-pstmt.c Sat Jul 5 15:50:46 2008
@@ -0,0 +1,96 @@
+/* GDA Firebird provider
+ * Copyright (C) 2008 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * TO_ADD: your name and email
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include "gda-firebird-pstmt.h"
+
+static void gda_firebird_pstmt_class_init (GdaFirebirdPStmtClass *klass);
+static void gda_firebird_pstmt_init (GdaFirebirdPStmt *pstmt, GdaFirebirdPStmtClass *klass);
+static void gda_firebird_pstmt_finalize (GObject *object);
+
+static GObjectClass *parent_class = NULL;
+
+/**
+ * gda_firebird_pstmt_get_type
+ *
+ * Returns: the #GType of GdaFirebirdPStmt.
+ */
+GType
+gda_firebird_pstmt_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static GStaticMutex registering = G_STATIC_MUTEX_INIT;
+ static const GTypeInfo info = {
+ sizeof (GdaFirebirdPStmtClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gda_firebird_pstmt_class_init,
+ NULL,
+ NULL,
+ sizeof (GdaFirebirdPStmt),
+ 0,
+ (GInstanceInitFunc) gda_firebird_pstmt_init
+ };
+
+ g_static_mutex_lock (®istering);
+ if (type == 0)
+ type = g_type_register_static (GDA_TYPE_PSTMT, "GdaFirebirdPStmt", &info, 0);
+ g_static_mutex_unlock (®istering);
+ }
+ return type;
+}
+
+static void
+gda_firebird_pstmt_class_init (GdaFirebirdPStmtClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ parent_class = g_type_class_peek_parent (klass);
+
+ /* virtual functions */
+ object_class->finalize = gda_firebird_pstmt_finalize;
+}
+
+static void
+gda_firebird_pstmt_init (GdaFirebirdPStmt *pstmt, GdaFirebirdPStmtClass *klass)
+{
+ g_return_if_fail (GDA_IS_PSTMT (pstmt));
+
+ /* initialize specific parts of @pstmt */
+ TO_IMPLEMENT;
+}
+
+static void
+gda_firebird_pstmt_finalize (GObject *object)
+{
+ GdaFirebirdPStmt *pstmt = (GdaFirebirdPStmt *) object;
+
+ g_return_if_fail (GDA_IS_PSTMT (pstmt));
+
+ /* free memory */
+ TO_IMPLEMENT; /* free some specific parts of @pstmt */
+
+ /* chain to parent class */
+ parent_class->finalize (object);
+}
Added: trunk/providers/firebird/gda-firebird-pstmt.h
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-pstmt.h Sat Jul 5 15:50:46 2008
@@ -0,0 +1,57 @@
+/* GDA Firebird library
+ * Copyright (C) 2008 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * TO_ADD: your name and email
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDA_FIREBIRD_PSTMT_H__
+#define __GDA_FIREBIRD_PSTMT_H__
+
+#include <providers-support/gda-pstmt.h>
+#include "gda-firebird.h"
+
+G_BEGIN_DECLS
+
+#define GDA_TYPE_FIREBIRD_PSTMT (gda_firebird_pstmt_get_type())
+#define GDA_FIREBIRD_PSTMT(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GDA_TYPE_FIREBIRD_PSTMT, GdaFirebirdPStmt))
+#define GDA_FIREBIRD_PSTMT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (klass, GDA_TYPE_FIREBIRD_PSTMT, GdaFirebirdPStmtClass))
+#define GDA_IS_FIREBIRD_PSTMT(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GDA_TYPE_FIREBIRD_PSTMT))
+#define GDA_IS_FIREBIRD_PSTMT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GDA_TYPE_FIREBIRD_PSTMT))
+
+typedef struct _GdaFirebirdPStmt GdaFirebirdPStmt;
+typedef struct _GdaFirebirdPStmtClass GdaFirebirdPStmtClass;
+
+struct _GdaFirebirdPStmt {
+ GdaPStmt object;
+
+ /* TO_ADD: this structure holds any information necessary to reference a prepared statement, usually a connection
+ * handle from the C or C++ API
+ */
+};
+
+struct _GdaFirebirdPStmtClass {
+ GdaPStmtClass parent_class;
+};
+
+GType gda_firebird_pstmt_get_type (void) G_GNUC_CONST;
+/* TO_ADD: helper function to create a GdaFirebirdPStmt such as gda_firebird_pstmt_new() with some specific arguments */
+
+G_END_DECLS
+
+#endif
Added: trunk/providers/firebird/gda-firebird-util.c
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-util.c Sat Jul 5 15:50:46 2008
@@ -0,0 +1,48 @@
+/* GDA firebird provider
+ * Copyright (C) 2008 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib/gi18n-lib.h>
+#include "gda-firebird-util.h"
+
+GdaConnectionEvent *
+_gda_firebird_make_error (GdaConnection *cnc, const gint statement_type)
+{
+ FirebirdConnectionData *cdata;
+ GdaConnectionEvent *error;
+ gchar *description;
+
+ g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+
+ cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data (cnc);
+ if (!cdata)
+ return FALSE;
+
+ error = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
+ gda_connection_event_set_code (error, isc_sqlcode (cdata->status));
+ description = fb_sqlerror_get_description (cdata, statement_type);
+ gda_connection_event_set_source (error, "[GDA Firebird]");
+ gda_connection_event_set_description (error, description);
+ gda_connection_add_event (cnc, error);
+ g_free (description);
+
+ return error;
+}
Added: trunk/providers/firebird/gda-firebird-util.h
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird-util.h Sat Jul 5 15:50:46 2008
@@ -0,0 +1,36 @@
+/* GDA firebird provider
+ * Copyright (C) 1998 - 2008 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Gonzalo Paniagua Javier <gonzalo gnome-db org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __GDA_FIREBIRD_UTIL_H__
+#define __GDA_FIREBIRD_UTIL_H__
+
+#include "gda-firebird.h"
+
+G_BEGIN_DECLS
+
+GdaConnectionEvent *_gda_firebird_make_error (GdaConnection *cnc, const gint statement_type);
+
+G_END_DECLS
+
+#endif
+
Added: trunk/providers/firebird/gda-firebird.h
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gda-firebird.h Sat Jul 5 15:50:46 2008
@@ -0,0 +1,48 @@
+c/* GDA firebird provider
+ * Copyright (C) 2008 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDA_FIREBIRD_H__
+#define __GDA_FIREBIRD_H__
+
+/*
+ * Provider name
+ */
+#define FIREBIRD_PROVIDER_NAME "Firebird"
+
+#include <ibase.h>
+
+/*
+ * Provider's specific connection data
+ */
+typedef struct {
+ gchar *dbname;
+ gchar *server_version;
+ isc_db_handle handle;
+ ISC_STATUS status[20];
+ gchar dpb_buffer[128];
+ gshort dpb_length;
+
+ /* transaction */
+ isc_tr_handle *ftr;
+} FirebirdConnectionData;
+
+#endif
Added: trunk/providers/firebird/gen_def.c
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/gen_def.c Sat Jul 5 15:50:46 2008
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2007 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This program generates tokens'ID transformation because the GdaSqlParser object uses 2 Lemon generated
+ * parsers at once, but with only one tokenizer (because each Lemon generated parser generates it own IDs for
+ * tokens).
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#define MAX_SYMBOLS 500
+#define PARSER_HEADER "parser.h"
+#define FALSE 0
+#define TRUE (!FALSE)
+
+typedef struct {
+ char *key;
+ int parser_value;
+} HashEntry;
+
+HashEntry entries[MAX_SYMBOLS];
+int nb_entries; /* must remain < MAX_SYMBOLS */
+
+typedef enum {
+ TYPE_IMPOSED,
+ TYPE_PARSER
+} SourceType;
+
+static void parse_contents (FILE *stream, SourceType type);
+static HashEntry *find_entry_for_token (char *token);
+int
+main (int argc,char** argv)
+{
+ int i;
+ FILE *fd_imposed;
+ FILE *fd_parser;
+ HashEntry *illegal_entry;
+ HashEntry *rawstring_entry;
+
+ memset (entries, 0, sizeof (entries));
+ fd_imposed = fopen (IMPOSED_HEADER, "r");
+ if (!fd_imposed) {
+ printf ("Can't open '%s':%s\n", IMPOSED_HEADER, strerror (errno));
+ return 1;
+ }
+ fd_parser = fopen (PARSER_HEADER, "r");
+ if (!fd_parser) {
+ printf ("Can't open '%s':%s\n", PARSER_HEADER, strerror (errno));
+ return 1;
+ }
+
+ nb_entries = 0;
+ parse_contents (fd_imposed, TYPE_IMPOSED);
+ parse_contents (fd_parser, TYPE_PARSER);
+
+ fclose (fd_imposed);
+ fclose (fd_parser);
+
+ /* output notice */
+ printf ("/*\n * This file is generated by the gen_def program (see the gen_def.c file \n"
+ " * for some explanations)\n"
+ " * DO NOT EDIT MANUALLY\n */\n\n\n");
+
+ /* output */
+ for (i = 0; i < nb_entries; i++) {
+ HashEntry *entry = &(entries[i]);
+ printf ("#define L_%s \t\t %d\n", entry->key, i);
+ }
+ illegal_entry = find_entry_for_token ("ILLEGAL");
+ rawstring_entry = find_entry_for_token ("RAWSTRING");
+ printf ("gint firebird_parser_tokens[] = {\n");
+ for (i = 0; i < nb_entries; i++) {
+ HashEntry *entry = &(entries[i]);
+ if (i!= 0)
+ printf (",");
+ if (entry->parser_value >= 0)
+ printf ("%d", entry->parser_value);
+ else
+ printf ("%d", illegal_entry->parser_value);
+ }
+ printf ("};\n");
+
+ return 0;
+}
+
+static HashEntry *
+find_entry_for_token (char *token)
+{
+ int i;
+
+ for (i = 0; i < nb_entries; i++) {
+ HashEntry *e = &(entries[i]);
+ if (!strcmp (e->key, token))
+ return e;
+ }
+ return NULL;
+}
+
+
+
+static void
+parse_line (char *line, SourceType type)
+{
+ char *z, *token;
+ int value;
+ HashEntry *entry;
+
+ z = line;
+ if (strncmp (z, "#define ", 8)) {
+ printf ("Expected '#define', not found");
+ exit (1);
+ }
+ z += 8;
+ token = z + 2;
+ for (; *z && *z != ' '; z++);
+ *z = 0;
+ z++;
+ for (; *z == ' '; z++);
+ value = atoi (z);
+ /*printf ("%d Token: /%s/, value=%d\n", type, token, value);*/
+
+ entry = find_entry_for_token (token);
+ if (!entry) {
+ nb_entries++;
+ entry = &(entries[nb_entries - 1]);
+ entry->key = malloc (sizeof (char) * (strlen (token) + 1));
+ memcpy (entry->key, token, strlen (token) + 1);
+ entry->parser_value = -1;
+ }
+ if (type == TYPE_PARSER)
+ entry->parser_value = value;
+}
+
+static void
+parse_contents (FILE *stream, SourceType type)
+{
+#define BUFSIZE 500
+ char buffer[BUFSIZE];
+ int read;
+ char *end;
+
+ read = fread (buffer, 1, BUFSIZE, stream);
+ end = buffer + read;
+ while (read > 0) {
+ char *ptr;
+
+ /* read all complete lines in buffer */
+ while (end > buffer) {
+ char *hold = NULL;
+ for (ptr = buffer; (ptr < end) && *ptr && (*ptr != '\n'); ptr++);
+ if (ptr == end)
+ break;
+ if (*ptr)
+ hold = ptr+1;
+ *ptr = 0;
+
+ /* treat the line */
+ parse_line (buffer, type);
+
+ if (hold) {
+ int l = end - hold;
+ end -= hold - buffer;
+ memmove (buffer, hold, l);
+ }
+ else
+ break;
+ }
+
+ read = fread (end, 1, BUFSIZE - (end - buffer), stream);
+ end += read;
+ }
+}
+
Added: trunk/providers/firebird/parser.y
==============================================================================
--- (empty file)
+++ trunk/providers/firebird/parser.y Sat Jul 5 15:50:46 2008
@@ -0,0 +1,1025 @@
+// All token codes are small integers with #defines that begin with "TK_"
+%token_prefix T_
+
+// The type of the data attached to each token is GValue. This is also the
+// default type for non-terminals.
+//
+%token_type {GValue *}
+%default_type {GValue *}
+%token_destructor {if ($$) {
+ gchar *str = gda_sql_value_stringify ($$);
+ DEBUG ("token destructor /%s/", str);
+ g_free (str);
+ g_value_unset ($$); g_free ($$);}}
+
+// The generated parser function takes a 4th argument as follows:
+%extra_argument {GdaSqlParserIface *pdata}
+
+// This code runs whenever there is a syntax error
+//
+%syntax_error {
+ gda_sql_parser_set_syntax_error (pdata->parser);
+}
+%stack_overflow {
+ gda_sql_parser_set_overflow_error (pdata->parser);
+}
+
+// The name of the generated procedure that implements the parser
+// is as follows:
+%name gda_lemon_firebird_parser
+
+// The following text is included near the beginning of the C source
+// code file that implements the parser.
+//
+%include {
+#include <string.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n-lib.h>
+#include <libgda/sql-parser/gda-sql-parser-private.h>
+#include <libgda/sql-parser/gda-statement-struct-util.h>
+#include <libgda/sql-parser/gda-statement-struct-trans.h>
+#include <libgda/sql-parser/gda-statement-struct-insert.h>
+#include <libgda/sql-parser/gda-statement-struct-update.h>
+#include <libgda/sql-parser/gda-statement-struct-delete.h>
+#include <libgda/sql-parser/gda-statement-struct-select.h>
+#include <libgda/sql-parser/gda-statement-struct-compound.h>
+#include <libgda/sql-parser/gda-statement-struct-parts.h>
+#include <assert.h>
+
+#ifdef GDA_DEBUG_NO
+#define DEBUG(format, ...) g_print ("___" format "\n", __VA_ARGS__)
+#else
+#define DEBUG(format, ...)
+#endif
+
+typedef struct {
+ GValue *fname;
+ GdaSqlExpr *expr;
+} UpdateSet;
+
+typedef struct {
+ gboolean distinct;
+ GdaSqlExpr *expr;
+} Distinct;
+
+typedef struct {
+ GdaSqlExpr *count;
+ GdaSqlExpr *offset;
+} Limit;
+
+typedef struct {
+ GSList *when_list;
+ GSList *then_list;
+} CaseBody;
+
+static GdaSqlOperatorType
+sql_operation_string_to_operator (const gchar *op)
+{
+ switch (g_ascii_toupper (*op)) {
+ case 'A':
+ return GDA_SQL_OPERATOR_TYPE_AND;
+ case 'O':
+ return GDA_SQL_OPERATOR_TYPE_OR;
+ case 'N':
+ return GDA_SQL_OPERATOR_TYPE_NOT;
+ case '=':
+ return GDA_SQL_OPERATOR_TYPE_EQ;
+ case 'I':
+ if (op[1] == 'S')
+ return GDA_SQL_OPERATOR_TYPE_IS;
+ else if (op[1] == 'N')
+ return GDA_SQL_OPERATOR_TYPE_IN;
+ break;
+ case 'L':
+ return GDA_SQL_OPERATOR_TYPE_LIKE;
+ case 'B':
+ return GDA_SQL_OPERATOR_TYPE_BETWEEN;
+ case '>':
+ if (op[1] == '=')
+ return GDA_SQL_OPERATOR_TYPE_GEQ;
+ else if (op[1] == 0)
+ return GDA_SQL_OPERATOR_TYPE_GT;
+ break;
+ case '<':
+ if (op[1] == '=')
+ return GDA_SQL_OPERATOR_TYPE_LEQ;
+ else if (op[1] == 0)
+ return GDA_SQL_OPERATOR_TYPE_LT;
+ break;
+ case '!':
+ if (op[1] == '=')
+ return GDA_SQL_OPERATOR_TYPE_DIFF;
+ else if (op[1] == '~') {
+ if (op[2] == 0)
+ return GDA_SQL_OPERATOR_TYPE_NOT_REGEXP;
+ else if (op[2] == '*')
+ return GDA_SQL_OPERATOR_TYPE_NOT_REGEXP_CI;
+ }
+ break;
+ case '~':
+ if (op[1] == '*')
+ return GDA_SQL_OPERATOR_TYPE_REGEXP_CI;
+ else if (op[1] == 0)
+ return GDA_SQL_OPERATOR_TYPE_REGEXP;
+ break;
+ case 'S':
+ return GDA_SQL_OPERATOR_TYPE_SIMILAR;
+ case '|':
+ if (op[1] == '|')
+ return GDA_SQL_OPERATOR_TYPE_CONCAT;
+ else
+ return GDA_SQL_OPERATOR_TYPE_BITOR;
+ case '+':
+ return GDA_SQL_OPERATOR_TYPE_PLUS;
+ case '-':
+ return GDA_SQL_OPERATOR_TYPE_MINUS;
+ case '*':
+ return GDA_SQL_OPERATOR_TYPE_STAR;
+ case '/':
+ return GDA_SQL_OPERATOR_TYPE_DIV;
+ case '%':
+ return GDA_SQL_OPERATOR_TYPE_REM;
+ case '&':
+ return GDA_SQL_OPERATOR_TYPE_BITAND;
+ }
+ g_error ("Unhandled operator named '%s'\n", op);
+ return 0;
+}
+
+static GdaSqlOperatorType
+string_to_op_type (GValue *value)
+{
+ GdaSqlOperatorType op;
+ op = sql_operation_string_to_operator (g_value_get_string (value));
+ g_value_reset (value);
+ g_free (value);
+ return op;
+}
+
+static GdaSqlExpr *
+compose_multiple_expr (GdaSqlOperatorType op, GdaSqlExpr *left, GdaSqlExpr *right) {
+ GdaSqlExpr *ret;
+ if (left->cond && (left->cond->operator == op)) {
+ ret = left;
+ ret->cond->operands = g_slist_append (ret->cond->operands, right);
+ }
+ else {
+ GdaSqlOperation *cond;
+ ret = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (ret));
+ ret->cond = cond;
+ cond->operator = op;
+ cond->operands = g_slist_prepend (NULL, right);
+ GDA_SQL_ANY_PART (right)->parent = GDA_SQL_ANY_PART (cond);
+ cond->operands = g_slist_prepend (cond->operands, left);
+ GDA_SQL_ANY_PART (left)->parent = GDA_SQL_ANY_PART (cond);
+ }
+ return ret;
+}
+
+static GdaSqlExpr *
+create_two_expr (GdaSqlOperatorType op, GdaSqlExpr *left, GdaSqlExpr *right) {
+ GdaSqlExpr *ret;
+ GdaSqlOperation *cond;
+ ret = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (ret));
+ ret->cond = cond;
+ cond->operator = op;
+ cond->operands = g_slist_prepend (NULL, right);
+ GDA_SQL_ANY_PART (right)->parent = GDA_SQL_ANY_PART (cond);
+ cond->operands = g_slist_prepend (cond->operands, left);
+ GDA_SQL_ANY_PART (left)->parent = GDA_SQL_ANY_PART (cond);
+ return ret;
+}
+
+static GdaSqlExpr *
+create_uni_expr (GdaSqlOperatorType op, GdaSqlExpr *expr) {
+ GdaSqlExpr *ret;
+ GdaSqlOperation *cond;
+ ret = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (ret));
+ ret->cond = cond;
+ cond->operator = op;
+ cond->operands = g_slist_prepend (NULL, expr);
+ GDA_SQL_ANY_PART (expr)->parent = GDA_SQL_ANY_PART (cond);
+ return ret;
+}
+
+static GdaSqlStatement *
+compose_multiple_compounds (GdaSqlStatementCompoundType ctype, GdaSqlStatement *left, GdaSqlStatement *right) {
+ GdaSqlStatement *ret;
+ GdaSqlStatementCompound *lc = (GdaSqlStatementCompound*) left->contents;
+ if (lc->compound_type == ctype) {
+ GdaSqlStatementCompound *rc = (GdaSqlStatementCompound*) right->contents;
+ if (!rc->stmt_list->next || rc->compound_type == ctype) {
+ GSList *list;
+ for (list = rc->stmt_list; list; list = list->next)
+ GDA_SQL_ANY_PART (((GdaSqlStatement*)list->data)->contents)->parent = GDA_SQL_ANY_PART (lc);
+
+ ret = left;
+ lc->stmt_list = g_slist_concat (lc->stmt_list, rc->stmt_list);
+ rc->stmt_list = NULL;
+ gda_sql_statement_free (right);
+ }
+ }
+ else {
+ ret = gda_sql_statement_new (GDA_SQL_STATEMENT_COMPOUND);
+ gda_sql_statement_compound_set_type (ret, ctype);
+ gda_sql_statement_compound_take_stmt (ret, left);
+ gda_sql_statement_compound_take_stmt (ret, right);
+ }
+ return ret;
+}
+
+}
+
+// The following directive causes tokens ABORT, AFTER, ASC, etc. to
+// fallback to ID if they will not parse as their original value.
+%fallback ID
+ ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT
+ DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
+ IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH PLAN
+ QUERY KEY OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW
+ TEMP TRIGGER VACUUM VIEW VIRTUAL
+ REINDEX RENAME CTIME_KW IF
+ DELIMITER COMMIT ROLLBACK ISOLATION LEVEL SERIALIZABLE READ COMMITTED
+ UNCOMMITTED REPEATABLE WRITE ONLY SAVEPOINT RELEASE COMMENT FORCE WAIT NOWAIT BATCH.
+
+// Define operator precedence early so that this is the first occurance
+// of the operator tokens in the grammer. Keeping the operators together
+// causes them to be assigned integer values that are close together,
+// which keeps parser tables smaller.
+%left OR.
+%left AND.
+%right NOT.
+%left IS MATCH LIKE IN ISNULL NOTNULL DIFF EQ.
+%left BETWEEN.
+%left GT LEQ LT GEQ.
+%left REGEXP REGEXP_CI NOT_REGEXP NOT_REGEXP_CI.
+%left SIMILAR.
+%right ESCAPE.
+%left BITAND BITOR LSHIFT RSHIFT.
+%left PLUS MINUS.
+%left STAR SLASH REM.
+%left CONCAT.
+%left COLLATE.
+%right UMINUS UPLUS BITNOT.
+%left LP RP.
+%left JOIN INNER NATURAL LEFT RIGHT FULL CROSS.
+%left UNION EXCEPT.
+%left INTERSECT.
+%left PGCAST.
+
+// force the declaration of the ILLEGAL and SQLCOMMENT tokens
+%nonassoc ILLEGAL.
+%nonassoc SQLCOMMENT.
+
+// Input is a single SQL command
+%type stmt {GdaSqlStatement *}
+%destructor stmt {g_print ("Statement destroyed by parser: %p\n", $$); gda_sql_statement_free ($$);}
+stmt ::= cmd(C) eos. {pdata->parsed_statement = C;}
+stmt ::= compound(C) eos. {
+ GdaSqlStatementCompound *scompound = (GdaSqlStatementCompound *) C->contents;
+ if (scompound->stmt_list->next)
+ /* real compound (multiple statements) */
+ pdata->parsed_statement = C;
+ else {
+ /* false compound (only 1 select) */
+ pdata->parsed_statement = (GdaSqlStatement*) scompound->stmt_list->data;
+ GDA_SQL_ANY_PART (pdata->parsed_statement->contents)->parent = NULL;
+ g_slist_free (scompound->stmt_list);
+ scompound->stmt_list = NULL;
+ gda_sql_statement_free (C);
+ }
+}
+cmd(C) ::= LP cmd(E) RP. {C = E;}
+compound(C) ::= LP compound(E) RP. {C = E;}
+
+eos ::= SEMI.
+eos ::= END_OF_FILE.
+
+%type cmd {GdaSqlStatement *}
+%destructor cmd {gda_sql_statement_free ($$);}
+
+//
+// Transactions
+//
+cmd(C) ::= BEGIN. {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);}
+cmd(C) ::= BEGIN TRANSACTION nm_opt(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= BEGIN transtype(Y) TRANSACTION nm_opt(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_take_mode (C, Y);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= BEGIN transtype(Y) nm_opt(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_take_mode (C, Y);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= BEGIN transilev(L). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_set_isol_level (C, L);
+}
+
+cmd(C) ::= BEGIN TRANSACTION transilev(L). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_set_isol_level (C, L);
+}
+
+cmd(C) ::= BEGIN TRANSACTION transtype(Y). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_take_mode (C, Y);
+}
+
+cmd(C) ::= BEGIN TRANSACTION transtype(Y) opt_comma transilev(L). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_take_mode (C, Y);
+ gda_sql_statement_trans_set_isol_level (C, L);
+}
+
+cmd(C) ::= BEGIN TRANSACTION transilev(L) opt_comma transtype(Y). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_take_mode (C, Y);
+ gda_sql_statement_trans_set_isol_level (C, L);
+}
+
+cmd(C) ::= BEGIN transtype(Y) opt_comma transilev(L). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_take_mode (C, Y);
+ gda_sql_statement_trans_set_isol_level (C, L);
+}
+
+cmd(C) ::= BEGIN transilev(L) opt_comma transtype(Y). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_BEGIN);
+ gda_sql_statement_trans_take_mode (C, Y);
+ gda_sql_statement_trans_set_isol_level (C, L);
+}
+
+cmd(C) ::= END trans_opt_kw nm_opt(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMMIT);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= COMMIT nm_opt(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMMIT);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= COMMIT TRANSACTION nm_opt(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMMIT);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= COMMIT FORCE STRING. {C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMMIT);}
+cmd(C) ::= COMMIT FORCE STRING COMMA INTEGER. {C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMMIT);}
+cmd(C) ::= COMMIT COMMENT STRING. {C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMMIT);}
+cmd(C) ::= COMMIT COMMENT STRING ora_commit_write. {C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMMIT);}
+cmd(C) ::= COMMIT ora_commit_write. {C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMMIT);}
+
+cmd(C) ::= ROLLBACK trans_opt_kw nm_opt(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_ROLLBACK);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+ora_commit_write ::= WRITE IMMEDIATE.
+ora_commit_write ::= WRITE BATCH.
+ora_commit_write ::= WRITE WAIT.
+ora_commit_write ::= WRITE NOWAIT.
+ora_commit_write ::= WRITE IMMEDIATE WAIT.
+ora_commit_write ::= WRITE IMMEDIATE NOWAIT.
+ora_commit_write ::= WRITE BATCH WAIT.
+ora_commit_write ::= WRITE BATCH NOWAIT.
+
+trans_opt_kw ::= .
+trans_opt_kw ::= TRANSACTION.
+
+opt_comma ::= .
+opt_comma ::= COMMA.
+
+%type transilev {GdaTransactionIsolation}
+transilev(L) ::= ISOLATION LEVEL SERIALIZABLE. {L = GDA_TRANSACTION_ISOLATION_SERIALIZABLE;}
+transilev(L) ::= ISOLATION LEVEL REPEATABLE READ. {L = GDA_TRANSACTION_ISOLATION_REPEATABLE_READ;}
+transilev(L) ::= ISOLATION LEVEL READ COMMITTED. {L = GDA_TRANSACTION_ISOLATION_READ_COMMITTED;}
+transilev(L) ::= ISOLATION LEVEL READ UNCOMMITTED. {L = GDA_TRANSACTION_ISOLATION_READ_UNCOMMITTED;}
+
+nm_opt(R) ::= . {R = NULL;}
+nm_opt(R) ::= nm(N). {R = N;}
+
+transtype(A) ::= DEFERRED(X). {A = X;}
+transtype(A) ::= IMMEDIATE(X). {A = X;}
+transtype(A) ::= EXCLUSIVE(X). {A = X;}
+transtype(A) ::= READ WRITE. {A = g_new0 (GValue, 1);
+ g_value_init (A, G_TYPE_STRING);
+ g_value_set_string (A, "READ_WRITE");
+}
+transtype(A) ::= READ ONLY. {A = g_new0 (GValue, 1);
+ g_value_init (A, G_TYPE_STRING);
+ g_value_set_string (A, "READ_ONLY");
+}
+
+//
+// Savepoints
+//
+cmd(C) ::= SAVEPOINT nm(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_SAVEPOINT);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= RELEASE SAVEPOINT nm(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_DELETE_SAVEPOINT);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= RELEASE nm(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_DELETE_SAVEPOINT);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= ROLLBACK trans_opt_kw TO nm(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_ROLLBACK_SAVEPOINT);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+cmd(C) ::= ROLLBACK trans_opt_kw TO SAVEPOINT nm(R). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_ROLLBACK_SAVEPOINT);
+ gda_sql_statement_trans_take_name (C, R);
+}
+
+//
+// INSERT
+//
+cmd(C) ::= INSERT opt_on_conflict(O) INTO fullname(X) inscollist_opt(F) VALUES LP exprlist(Y) RP. {
+ C = gda_sql_statement_new (GDA_SQL_STATEMENT_INSERT);
+ gda_sql_statement_insert_take_table_name (C, X);
+ gda_sql_statement_insert_take_fields_list (C, F);
+ gda_sql_statement_insert_take_1_values_list (C, Y);
+ gda_sql_statement_insert_take_on_conflict (C, O);
+}
+
+cmd(C) ::= INSERT opt_on_conflict(O) INTO fullname(X) inscollist_opt(F) VALUES LP exprlist(Y) RP ins_extra_values(E). {
+ C = gda_sql_statement_new (GDA_SQL_STATEMENT_INSERT);
+ gda_sql_statement_insert_take_table_name (C, X);
+ gda_sql_statement_insert_take_fields_list (C, F);
+ gda_sql_statement_insert_take_1_values_list (C, Y);
+ gda_sql_statement_insert_take_extra_values_list (C, E);
+ gda_sql_statement_insert_take_on_conflict (C, O);
+}
+
+cmd(C) ::= INSERT opt_on_conflict(O) INTO fullname(X) inscollist_opt(F) compound(S). {
+ C = gda_sql_statement_new (GDA_SQL_STATEMENT_INSERT);
+ gda_sql_statement_insert_take_table_name (C, X);
+ gda_sql_statement_insert_take_fields_list (C, F);
+ gda_sql_statement_insert_take_select (C, S);
+ gda_sql_statement_insert_take_on_conflict (C, O);
+}
+
+
+opt_on_conflict(O) ::= . {O = NULL;}
+opt_on_conflict(O) ::= OR ID(V). {O = V;}
+
+%type ins_extra_values {GSList*}
+%destructor ins_extra_values {GSList *list;
+ for (list = $$; list; list = list->next) {
+ g_slist_foreach ((GSList*) list->data, (GFunc) gda_sql_field_free, NULL);
+ g_slist_free ((GSList*) list->data);
+ }
+ g_slist_free ($$);
+}
+ins_extra_values(E) ::= ins_extra_values(A) COMMA LP exprlist(L) RP. {E = g_slist_append (A, L);}
+ins_extra_values(E) ::= COMMA LP exprlist(L) RP. {E = g_slist_append (NULL, L);}
+
+%type inscollist_opt {GSList*}
+%destructor inscollist_opt {if ($$) {g_slist_foreach ($$, (GFunc) gda_sql_field_free, NULL); g_slist_free ($$);}}
+inscollist_opt(A) ::= . {A = NULL;}
+inscollist_opt(A) ::= LP inscollist(X) RP. {A = X;}
+
+%type inscollist {GSList*}
+%destructor inscollist {if ($$) {g_slist_foreach ($$, (GFunc) gda_sql_field_free, NULL); g_slist_free ($$);}}
+inscollist(A) ::= inscollist(X) COMMA fullname(Y). {GdaSqlField *field;
+ field = gda_sql_field_new (NULL);
+ gda_sql_field_take_name (field, Y);
+ A = g_slist_append (X, field);
+}
+inscollist(A) ::= fullname(Y). {GdaSqlField *field = gda_sql_field_new (NULL);
+ gda_sql_field_take_name (field, Y);
+ A = g_slist_prepend (NULL, field);
+}
+
+// DELETE
+cmd(C) ::= DELETE FROM fullname(T) where_opt(X). {C = gda_sql_statement_new (GDA_SQL_STATEMENT_DELETE);
+ gda_sql_statement_delete_take_table_name (C, T);
+ gda_sql_statement_delete_take_condition (C, X);}
+
+%type where_opt {GdaSqlExpr *}
+%destructor where_opt {gda_sql_expr_free ($$);}
+where_opt(A) ::= . {A = NULL;}
+where_opt(A) ::= WHERE expr(X). {A = X;}
+
+// UPDATE
+cmd(C) ::= UPDATE opt_on_conflict(O) fullname(T) SET setlist(S) where_opt(X). {
+ GSList *list;
+ C = gda_sql_statement_new (GDA_SQL_STATEMENT_UPDATE);
+ gda_sql_statement_update_take_table_name (C, T);
+ gda_sql_statement_update_take_on_conflict (C, O);
+ gda_sql_statement_update_take_condition (C, X);
+ for (list = S; list; list = list->next) {
+ UpdateSet *set = (UpdateSet*) list->data;
+ gda_sql_statement_update_take_set_value (C, set->fname, set->expr);
+ g_free (set);
+ }
+ g_slist_free (S);
+}
+
+%type setlist {GSList*}
+%destructor setlist {GSList *list;
+ for (list = $$; list; list = list->next) {
+ UpdateSet *set = (UpdateSet*) list->data;
+ g_value_reset (set->fname); g_free (set->fname);
+ gda_sql_expr_free (set->expr);
+ g_free (set);
+ }
+ g_slist_free ($$);
+}
+setlist(A) ::= setlist(Z) COMMA fullname(X) EQ expr(Y). {UpdateSet *set;
+ set = g_new (UpdateSet, 1);
+ set->fname = X;
+ set->expr = Y;
+ A = g_slist_append (Z, set);
+}
+setlist(A) ::= fullname(X) EQ expr(Y). {UpdateSet *set;
+ set = g_new (UpdateSet, 1);
+ set->fname = X;
+ set->expr = Y;
+ A = g_slist_append (NULL, set);
+}
+
+// COMPOUND SELECT
+%type compound {GdaSqlStatement *}
+%destructor compound {gda_sql_statement_free ($$);}
+//compound(C) ::= LP compound(E) RP. {C = E;}
+compound(C) ::= selectcmd(S). {
+ C = gda_sql_statement_new (GDA_SQL_STATEMENT_COMPOUND);
+ gda_sql_statement_compound_take_stmt (C, S);
+}
+compound(C) ::= compound(L) UNION opt_compound_all(A) compound(R). {
+ C = compose_multiple_compounds (A ? GDA_SQL_STATEMENT_COMPOUND_UNION_ALL : GDA_SQL_STATEMENT_COMPOUND_UNION,
+ L, R);
+}
+
+compound(C) ::= compound(L) EXCEPT opt_compound_all(A) compound(R). {
+ C = compose_multiple_compounds (A ? GDA_SQL_STATEMENT_COMPOUND_EXCEPT_ALL : GDA_SQL_STATEMENT_COMPOUND_EXCEPT,
+ L, R);
+}
+
+compound(C) ::= compound(L) INTERSECT opt_compound_all(A) compound(R). {
+ C = compose_multiple_compounds (A ? GDA_SQL_STATEMENT_COMPOUND_INTERSECT_ALL : GDA_SQL_STATEMENT_COMPOUND_INTERSECT,
+ L, R);
+}
+
+%type opt_compound_all {gboolean}
+opt_compound_all(A) ::= . {A = FALSE;}
+opt_compound_all(A) ::= ALL. {A = TRUE;}
+
+
+// SELECT
+%type selectcmd {GdaSqlStatement *}
+%destructor selectcmd {gda_sql_statement_free ($$);}
+selectcmd(C) ::= SELECT distinct(D) selcollist(W) from(F) where_opt(Y)
+ groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
+ C = gda_sql_statement_new (GDA_SQL_STATEMENT_SELECT);
+ if (D) {
+ gda_sql_statement_select_take_distinct (C, D->distinct, D->expr);
+ g_free (D);
+ }
+ gda_sql_statement_select_take_expr_list (C, W);
+ gda_sql_statement_select_take_from (C, F);
+ gda_sql_statement_select_take_where_cond (C, Y);
+ gda_sql_statement_select_take_group_by (C, P);
+ gda_sql_statement_select_take_having_cond (C, Q);
+ gda_sql_statement_select_take_order_by (C, Z);
+ gda_sql_statement_select_take_limits (C, L.count, L.offset);
+}
+
+%type limit_opt {Limit}
+%destructor limit_opt {gda_sql_expr_free ($$.count); gda_sql_expr_free ($$.offset);}
+limit_opt(A) ::= . {A.count = NULL; A.offset = NULL;}
+limit_opt(A) ::= LIMIT expr(X). {A.count = X; A.offset = NULL;}
+limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). {A.count = X; A.offset = Y;}
+limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). {A.count = X; A.offset = Y;}
+
+%type orderby_opt {GSList *}
+%destructor orderby_opt {if ($$) {g_slist_foreach ($$, (GFunc) gda_sql_select_order_free, NULL); g_slist_free ($$);}}
+orderby_opt(A) ::= . {A = 0;}
+orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
+
+%type sortlist {GSList *}
+%destructor sortlist {if ($$) {g_slist_foreach ($$, (GFunc) gda_sql_select_order_free, NULL); g_slist_free ($$);}}
+sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {GdaSqlSelectOrder *order;
+ order = gda_sql_select_order_new (NULL);
+ order->expr = Y;
+ order->asc = Z;
+ A = g_slist_append (X, order);
+}
+sortlist(A) ::= expr(Y) sortorder(Z). {GdaSqlSelectOrder *order;
+ order = gda_sql_select_order_new (NULL);
+ order->expr = Y;
+ order->asc = Z;
+ A = g_slist_prepend (NULL, order);
+}
+
+%type sortorder {gboolean}
+sortorder(A) ::= ASC. {A = TRUE;}
+sortorder(A) ::= DESC. {A = FALSE;}
+sortorder(A) ::= . {A = TRUE;}
+
+
+%type having_opt {GdaSqlExpr *}
+%destructor having_opt {gda_sql_expr_free ($$);}
+having_opt(A) ::= . {A = NULL;}
+having_opt(A) ::= HAVING expr(X). {A = X;}
+
+%type groupby_opt {GSList*}
+%destructor groupby_opt {if ($$) {g_slist_foreach ($$, (GFunc) gda_sql_expr_free, NULL); g_slist_free ($$);}}
+groupby_opt(A) ::= . {A = 0;}
+groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;}
+
+%type from {GdaSqlSelectFrom *}
+%destructor from {gda_sql_select_from_free ($$);}
+from(F) ::= . {F = NULL;}
+from(F) ::= FROM seltablist(X). {F = X;}
+
+%type seltablist {GdaSqlSelectFrom *}
+%destructor seltablist {gda_sql_select_from_free ($$);}
+%type stl_prefix {GdaSqlSelectFrom *}
+%destructor stl_prefix {gda_sql_select_from_free ($$);}
+
+seltablist(L) ::= stl_prefix(P) seltarget(T) on_cond(C) using_opt(U). {
+ GSList *last;
+ if (P)
+ L = P;
+ else
+ L = gda_sql_select_from_new (NULL);
+ gda_sql_select_from_take_new_target (L, T);
+ last = g_slist_last (L->joins);
+ if (last) {
+ GdaSqlSelectJoin *join = (GdaSqlSelectJoin *) (last->data);
+ join->expr = C;
+ join->position = g_slist_length (L->targets) - 1;
+ join->using = U;
+ }
+}
+
+%type using_opt {GSList*}
+%destructor using_opt {if ($$) {g_slist_foreach ($$, (GFunc) gda_sql_field_free, NULL); g_slist_free ($$);}}
+using_opt(U) ::= USING LP inscollist(L) RP. {U = L;}
+using_opt(U) ::= . {U = NULL;}
+
+stl_prefix(P) ::= . {P = NULL;}
+stl_prefix(P) ::= seltablist(L) jointype(J). {GdaSqlSelectJoin *join;
+ P = L;
+ join = gda_sql_select_join_new (GDA_SQL_ANY_PART (P));
+ join->type = J;
+ gda_sql_select_from_take_new_join (P, join);
+}
+
+
+%type on_cond {GdaSqlExpr *}
+%destructor on_cond {gda_sql_expr_free ($$);}
+on_cond(N) ::= ON expr(E). {N = E;}
+on_cond(N) ::= . {N = NULL;}
+
+%type jointype {GdaSqlSelectJoinType}
+jointype(J) ::= COMMA. {J = GDA_SQL_SELECT_JOIN_CROSS;}
+jointype(J) ::= JOIN. {J = GDA_SQL_SELECT_JOIN_INNER;}
+jointype(J) ::= CROSS JOIN. {J = GDA_SQL_SELECT_JOIN_CROSS;}
+jointype(J) ::= INNER JOIN. {J = GDA_SQL_SELECT_JOIN_INNER;}
+jointype(J) ::= NATURAL JOIN. {J = GDA_SQL_SELECT_JOIN_NATURAL;}
+jointype(J) ::= LEFT JOIN. {J = GDA_SQL_SELECT_JOIN_LEFT;}
+jointype(J) ::= LEFT OUTER JOIN. {J = GDA_SQL_SELECT_JOIN_LEFT;}
+jointype(J) ::= RIGHT JOIN. {J = GDA_SQL_SELECT_JOIN_RIGHT;}
+jointype(J) ::= RIGHT OUTER JOIN. {J = GDA_SQL_SELECT_JOIN_RIGHT;}
+jointype(J) ::= FULL JOIN. {J = GDA_SQL_SELECT_JOIN_FULL;}
+jointype(J) ::= FULL OUTER JOIN. {J = GDA_SQL_SELECT_JOIN_FULL;}
+
+
+%type seltarget {GdaSqlSelectTarget *}
+%destructor seltarget {gda_sql_select_target_free ($$);}
+seltarget(T) ::= fullname(F) as(A). {T = gda_sql_select_target_new (NULL);
+ gda_sql_select_target_take_alias (T, A);
+ gda_sql_select_target_take_table_name (T, F);
+}
+seltarget(T) ::= fullname(F) ID(A). {T = gda_sql_select_target_new (NULL);
+ gda_sql_select_target_take_alias (T, A);
+ gda_sql_select_target_take_table_name (T, F);
+}
+seltarget(T) ::= LP compound(S) RP as(A). {T = gda_sql_select_target_new (NULL);
+ gda_sql_select_target_take_alias (T, A);
+ gda_sql_select_target_take_select (T, S);
+}
+
+%type selcollist {GSList *}
+%destructor selcollist {g_slist_foreach ($$, (GFunc) gda_sql_select_field_free, NULL); g_slist_free ($$);}
+
+%type sclp {GSList *}
+%destructor sclp {g_slist_foreach ($$, (GFunc) gda_sql_select_field_free, NULL); g_slist_free ($$);}
+sclp(A) ::= selcollist(X) COMMA. {A = X;}
+sclp(A) ::= . {A = NULL;}
+
+selcollist(L) ::= sclp(E) expr(X) as(A). {GdaSqlSelectField *field;
+ field = gda_sql_select_field_new (NULL);
+ gda_sql_select_field_take_expr (field, X);
+ gda_sql_select_field_take_alias (field, A);
+ L = g_slist_append (E, field);}
+selcollist(L) ::= sclp(E) starname(X). {GdaSqlSelectField *field;
+ field = gda_sql_select_field_new (NULL);
+ gda_sql_select_field_take_star_value (field, X);
+ L = g_slist_append (E, field);}
+
+starname(S) ::= STAR(X). {S = X;}
+starname(A) ::= nm(S) DOT STAR(X). {gchar *str;
+ str = g_strdup_printf ("%s.%s", g_value_get_string (S), g_value_get_string (X));
+ A = g_new0 (GValue, 1);
+ g_value_init (A, G_TYPE_STRING);
+ g_value_take_string (A, str);
+ g_value_reset (S); g_free (S);
+ g_value_reset (X); g_free (X);
+}
+
+starname(A) ::= nm(C) DOT nm(S) DOT STAR(X). {gchar *str;
+ str = g_strdup_printf ("%s.%s.%s", g_value_get_string (C),
+ g_value_get_string (S), g_value_get_string (X));
+ A = g_new0 (GValue, 1);
+ g_value_init (A, G_TYPE_STRING);
+ g_value_take_string (A, str);
+ g_value_reset (C); g_free (C);
+ g_value_reset (S); g_free (S);
+ g_value_reset (X); g_free (X);
+}
+
+as(A) ::= AS fullname(F). {A = F;}
+as(A) ::= AS value(F). {A = F;}
+as(A) ::= . {A = NULL;}
+
+%type distinct {Distinct *}
+%destructor distinct {if ($$) {if ($$->expr) gda_sql_expr_free ($$->expr); g_free ($$);}}
+distinct(E) ::= . {E = NULL;}
+distinct(E) ::= ALL. {E = NULL;}
+distinct(E) ::= DISTINCT. {E = g_new0 (Distinct, 1); E->distinct = TRUE;}
+distinct(E) ::= DISTINCT ON expr(X). [OR] {E = g_new0 (Distinct, 1); E->distinct = TRUE; E->expr = X;}
+
+// Non empty list of expressions
+%type nexprlist {GSList *}
+%destructor nexprlist {if ($$) {g_slist_foreach ($$, (GFunc) gda_sql_expr_free, NULL); g_slist_free ($$);}}
+nexprlist(L) ::= nexprlist(E) COMMA expr(X). {L = g_slist_append (E, X);}
+nexprlist(L) ::= expr(E). {L = g_slist_append (NULL, E);}
+
+// List of expressions
+%type exprlist {GSList *}
+%destructor exprlist {if ($$) {g_slist_foreach ($$, (GFunc) gda_sql_expr_free, NULL); g_slist_free ($$);}}
+exprlist(L) ::= . {L = NULL;}
+exprlist(L) ::= exprlist(E) COMMA expr(X). {L = g_slist_append (E, X);}
+exprlist(L) ::= expr(E). {L = g_slist_append (NULL, E);}
+
+// A single expression
+%type expr {GdaSqlExpr *}
+%destructor expr {gda_sql_expr_free ($$);}
+expr(E) ::= pvalue(V). {E = V;}
+expr(E) ::= value(V). {E = gda_sql_expr_new (NULL); E->value = V;}
+expr(E) ::= LP expr(X) RP. {E = X;}
+expr(E) ::= fullname(V). {E = gda_sql_expr_new (NULL); E->value = V;}
+expr(E) ::= fullname(V) LP exprlist(A) RP. {GdaSqlFunction *func;
+ E = gda_sql_expr_new (NULL);
+ func = gda_sql_function_new (GDA_SQL_ANY_PART (E));
+ gda_sql_function_take_name (func, V);
+ gda_sql_function_take_args_list (func, A);
+ E->func = func;}
+expr(E) ::= fullname(V) LP compound(S) RP. {GdaSqlFunction *func;
+ GdaSqlExpr *expr;
+ E = gda_sql_expr_new (NULL);
+ func = gda_sql_function_new (GDA_SQL_ANY_PART (E));
+ gda_sql_function_take_name (func, V);
+ expr = gda_sql_expr_new (GDA_SQL_ANY_PART (func));
+ gda_sql_expr_take_select (expr, S);
+ gda_sql_function_take_args_list (func, g_slist_prepend (NULL, expr));
+ E->func = func;}
+expr(E) ::= fullname(V) LP starname(A) RP. {GdaSqlFunction *func;
+ GdaSqlExpr *expr;
+ E = gda_sql_expr_new (NULL);
+ func = gda_sql_function_new (GDA_SQL_ANY_PART (E));
+ gda_sql_function_take_name (func, V);
+ expr = gda_sql_expr_new (GDA_SQL_ANY_PART (func));
+ expr->value = A;
+ gda_sql_function_take_args_list (func, g_slist_prepend (NULL, expr));
+ E->func = func;}
+expr(E) ::= CAST LP expr(A) AS fullname(T) RP. {E = A;
+ A->cast_as = g_value_dup_string (T);
+ g_value_reset (T);
+ g_free (T);}
+expr(E) ::= expr(A) PGCAST fullname(T). {E = A;
+ A->cast_as = g_value_dup_string (T);
+ g_value_reset (T);
+ g_free (T);}
+
+expr(C) ::= expr(L) PLUS|MINUS(O) expr(R). {C = compose_multiple_expr (string_to_op_type (O), L, R);}
+expr(C) ::= expr(L) STAR expr(R). {C = compose_multiple_expr (GDA_SQL_OPERATOR_TYPE_STAR, L, R);}
+expr(C) ::= expr(L) SLASH|REM(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
+expr(C) ::= expr(L) BITAND|BITOR(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
+
+expr(C) ::= MINUS expr(X). [UMINUS] {C = create_uni_expr (GDA_SQL_OPERATOR_TYPE_MINUS, X);}
+expr(C) ::= PLUS expr(X). [UPLUS] {C = create_uni_expr (GDA_SQL_OPERATOR_TYPE_PLUS, X);}
+
+expr(C) ::= expr(L) AND expr(R). {C = compose_multiple_expr (GDA_SQL_OPERATOR_TYPE_AND, L, R);}
+expr(C) ::= expr(L) OR expr(R). {C = compose_multiple_expr (GDA_SQL_OPERATOR_TYPE_OR, L, R);}
+expr(C) ::= expr(L) CONCAT expr(R). {C = compose_multiple_expr (GDA_SQL_OPERATOR_TYPE_CONCAT, L, R);}
+
+expr(C) ::= expr(L) GT|LEQ|GEQ|LT(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
+expr(C) ::= expr(L) DIFF|EQ(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
+expr(C) ::= expr(L) LIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_LIKE, L, R);}
+expr(C) ::= expr(L) REGEXP|REGEXP_CI|NOT_REGEXP|NOT_REGEXP_CI|SIMILAR(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
+expr(C) ::= expr(L) BETWEEN expr(R) AND expr(E). {GdaSqlOperation *cond;
+ C = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (C));
+ C->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_BETWEEN;
+ cond->operands = g_slist_append (NULL, L);
+ GDA_SQL_ANY_PART (L)->parent = GDA_SQL_ANY_PART (cond);
+ cond->operands = g_slist_append (cond->operands, R);
+ GDA_SQL_ANY_PART (R)->parent = GDA_SQL_ANY_PART (cond);
+ cond->operands = g_slist_append (cond->operands, E);
+ GDA_SQL_ANY_PART (E)->parent = GDA_SQL_ANY_PART (cond);
+}
+
+expr(C) ::= expr(L) NOT BETWEEN expr(R) AND expr(E). {GdaSqlOperation *cond;
+ GdaSqlExpr *expr;
+ expr = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (expr));
+ expr->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_BETWEEN;
+ cond->operands = g_slist_append (NULL, L);
+ GDA_SQL_ANY_PART (L)->parent = GDA_SQL_ANY_PART (cond);
+ cond->operands = g_slist_append (cond->operands, R);
+ GDA_SQL_ANY_PART (R)->parent = GDA_SQL_ANY_PART (cond);
+ cond->operands = g_slist_append (cond->operands, E);
+ GDA_SQL_ANY_PART (E)->parent = GDA_SQL_ANY_PART (cond);
+
+ C = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (C));
+ C->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_NOT;
+ cond->operands = g_slist_prepend (NULL, expr);
+ GDA_SQL_ANY_PART (expr)->parent = GDA_SQL_ANY_PART (cond);
+}
+
+expr(C) ::= NOT expr(R). {C = create_uni_expr (GDA_SQL_OPERATOR_TYPE_NOT, R);}
+expr(C) ::= BITNOT expr(R). {C = create_uni_expr (GDA_SQL_OPERATOR_TYPE_BITNOT, R);}
+expr(C) ::= expr(R) uni_op(O) . {C = create_uni_expr (O, R);}
+
+expr(C) ::= expr(L) IS expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_IS, L, R);}
+expr(E) ::= LP compound(S) RP. {E = gda_sql_expr_new (NULL); gda_sql_expr_take_select (E, S);}
+expr(E) ::= expr(R) IN LP exprlist(L) RP. {GdaSqlOperation *cond;
+ GSList *list;
+ E = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (E));
+ E->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_IN;
+ cond->operands = g_slist_prepend (L, R);
+ for (list = cond->operands; list; list = list->next)
+ GDA_SQL_ANY_PART (list->data)->parent = GDA_SQL_ANY_PART (cond);
+}
+expr(E) ::= expr(R) IN LP compound(S) RP. {GdaSqlOperation *cond;
+ GdaSqlExpr *expr;
+ E = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (E));
+ E->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_IN;
+
+ expr = gda_sql_expr_new (GDA_SQL_ANY_PART (cond));
+ gda_sql_expr_take_select (expr, S);
+ cond->operands = g_slist_prepend (NULL, expr);
+ cond->operands = g_slist_prepend (cond->operands, R);
+ GDA_SQL_ANY_PART (R)->parent = GDA_SQL_ANY_PART (cond);
+}
+expr(E) ::= expr(R) NOT IN LP exprlist(L) RP. {GdaSqlOperation *cond;
+ GdaSqlExpr *expr;
+ GSList *list;
+ expr = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (expr));
+ expr->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_IN;
+ cond->operands = g_slist_prepend (L, R);
+ for (list = cond->operands; list; list = list->next)
+ GDA_SQL_ANY_PART (list->data)->parent = GDA_SQL_ANY_PART (cond);
+
+ E = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (E));
+ E->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_NOT;
+ cond->operands = g_slist_prepend (NULL, expr);
+ GDA_SQL_ANY_PART (expr)->parent = GDA_SQL_ANY_PART (cond);
+}
+expr(E) ::= expr(R) NOT IN LP compound(S) RP. {GdaSqlOperation *cond;
+ GdaSqlExpr *expr1, *expr2;
+ expr1 = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (expr1));
+ expr1->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_IN;
+
+ expr2 = gda_sql_expr_new (NULL);
+ gda_sql_expr_take_select (expr2, S);
+ cond->operands = g_slist_prepend (NULL, expr2);
+ GDA_SQL_ANY_PART (expr2)->parent = GDA_SQL_ANY_PART (cond);
+ cond->operands = g_slist_prepend (cond->operands, R);
+ GDA_SQL_ANY_PART (R)->parent = GDA_SQL_ANY_PART (cond);
+
+ E = gda_sql_expr_new (NULL);
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (E));
+ E->cond = cond;
+ cond->operator = GDA_SQL_OPERATOR_TYPE_NOT;
+ cond->operands = g_slist_prepend (NULL, expr1);
+ GDA_SQL_ANY_PART (expr1)->parent = GDA_SQL_ANY_PART (cond);
+}
+expr(A) ::= CASE case_operand(X) case_exprlist(Y) case_else(Z) END. {
+ GdaSqlCase *sc;
+ GSList *list;
+ A = gda_sql_expr_new (NULL);
+ sc = gda_sql_case_new (GDA_SQL_ANY_PART (A));
+ sc->base_expr = X;
+ sc->else_expr = Z;
+ sc->when_expr_list = Y.when_list;
+ sc->then_expr_list = Y.then_list;
+ A->case_s = sc;
+ for (list = sc->when_expr_list; list; list = list->next)
+ GDA_SQL_ANY_PART (list->data)->parent = GDA_SQL_ANY_PART (sc);
+ for (list = sc->then_expr_list; list; list = list->next)
+ GDA_SQL_ANY_PART (list->data)->parent = GDA_SQL_ANY_PART (sc);
+}
+
+%type case_operand {GdaSqlExpr*}
+%destructor case_operand {gda_sql_expr_free ($$);}
+case_operand(A) ::= expr(X). {A = X;}
+case_operand(A) ::= . {A = NULL;}
+
+%type case_exprlist {CaseBody}
+%destructor case_exprlist {g_slist_foreach ($$.when_list, (GFunc) gda_sql_expr_free, NULL); g_slist_free ($$.when_list);
+ g_slist_foreach ($$.then_list, (GFunc) gda_sql_expr_free, NULL); g_slist_free ($$.then_list);}
+
+case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
+ A.when_list = g_slist_append (X.when_list, Y);
+ A.then_list = g_slist_append (X.then_list, Z);
+}
+case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
+ A.when_list = g_slist_prepend (NULL, Y);
+ A.then_list = g_slist_prepend (NULL, Z);
+}
+
+%type case_else {GdaSqlExpr*}
+%destructor case_else {gda_sql_expr_free ($$);}
+case_else(A) ::= ELSE expr(X). {A = X;}
+case_else(A) ::= . {A = NULL;}
+
+%type uni_op {GdaSqlOperatorType}
+uni_op(O) ::= ISNULL. {O = GDA_SQL_OPERATOR_TYPE_ISNULL;}
+uni_op(O) ::= IS NOTNULL. {O = GDA_SQL_OPERATOR_TYPE_ISNOTNULL;}
+
+
+// Values: for all constants (G_TYPE_STRING GValue)
+value(V) ::= NULL. {V = NULL;}
+value(V) ::= STRING(S). {V = S;}
+value(V) ::= TEXTUAL(T). {V = T;}
+value(V) ::= INTEGER(I). {V = I;}
+value(V) ::= FLOAT(F). {V = F;}
+
+// pvalue: values which are parameters (GdaSqlExpr)
+%type pvalue {GdaSqlExpr *}
+%destructor pvalue {gda_sql_expr_free ($$);}
+ pvalue(E) ::= UNSPECVAL LSBRACKET paramspec(P) RSBRACKET. {E = gda_sql_expr_new (NULL); E->param_spec = P;}
+pvalue(E) ::= value(V) LSBRACKET paramspec(P) RSBRACKET. {E = gda_sql_expr_new (NULL); E->value = V; E->param_spec = P;}
+pvalue(E) ::= SIMPLEPARAM(S). {E = gda_sql_expr_new (NULL); E->param_spec = gda_sql_param_spec_new (S);}
+
+// paramspec: parameter's specifications
+%type paramspec {GdaSqlParamSpec *}
+%destructor paramspec {gda_sql_param_spec_free ($$);}
+paramspec(P) ::= . {P = NULL;}
+paramspec(P) ::= paramspec(E) PNAME(N). {if (!E) P = gda_sql_param_spec_new (NULL); else P = E;
+ gda_sql_param_spec_take_name (P, N);}
+paramspec(P) ::= paramspec(E) PDESCR(N). {if (!E) P = gda_sql_param_spec_new (NULL); else P = E;
+ gda_sql_param_spec_take_descr (P, N);}
+paramspec(P) ::= paramspec(E) PTYPE(N). {if (!E) P = gda_sql_param_spec_new (NULL); else P = E;
+ gda_sql_param_spec_take_type (P, N);}
+paramspec(P) ::= paramspec(E) PNULLOK(N). {if (!E) P = gda_sql_param_spec_new (NULL); else P = E;
+ gda_sql_param_spec_take_nullok (P, N);}
+
+// The name of a column or table can be any of the following:
+//
+nm(A) ::= JOIN(X). {A = X;}
+nm(A) ::= ID(X). {A = X;}
+nm(A) ::= TEXTUAL(X). {A = X;}
+
+// Fully qualified name
+fullname(A) ::= nm(S) DOT nm(X). {gchar *str;
+ str = g_strdup_printf ("%s.%s", g_value_get_string (S), g_value_get_string (X));
+ A = g_new0 (GValue, 1);
+ g_value_init (A, G_TYPE_STRING);
+ g_value_take_string (A, str);
+ g_value_reset (S); g_free (S);
+ g_value_reset (X); g_free (X);
+}
+
+fullname(A) ::= nm(C) DOT nm(S) DOT nm(X). {gchar *str;
+ str = g_strdup_printf ("%s.%s.%s", g_value_get_string (C),
+ g_value_get_string (S), g_value_get_string (X));
+ A = g_new0 (GValue, 1);
+ g_value_init (A, G_TYPE_STRING);
+ g_value_take_string (A, str);
+ g_value_reset (C); g_free (C);
+ g_value_reset (S); g_free (S);
+ g_value_reset (X); g_free (X);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]