LCOV - code coverage report
Current view: top level - connectivity/source/drivers/postgresql - pq_databasemetadata.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 809 0.0 %
Date: 2012-08-25 Functions: 0 172 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  *  Effective License of whole file:
       5                 :            :  *
       6                 :            :  *    This library is free software; you can redistribute it and/or
       7                 :            :  *    modify it under the terms of the GNU Lesser General Public
       8                 :            :  *    License version 2.1, as published by the Free Software Foundation.
       9                 :            :  *
      10                 :            :  *    This library is distributed in the hope that it will be useful,
      11                 :            :  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12                 :            :  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13                 :            :  *    Lesser General Public License for more details.
      14                 :            :  *
      15                 :            :  *    You should have received a copy of the GNU Lesser General Public
      16                 :            :  *    License along with this library; if not, write to the Free Software
      17                 :            :  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
      18                 :            :  *    MA  02111-1307  USA
      19                 :            :  *
      20                 :            :  *  Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
      21                 :            :  *
      22                 :            :  *    The Contents of this file are made available subject to the terms of
      23                 :            :  *    the GNU Lesser General Public License Version 2.1
      24                 :            :  *
      25                 :            :  *    Copyright: 2000 by Sun Microsystems, Inc.
      26                 :            :  *
      27                 :            :  *    Contributor(s): Joerg Budischewski
      28                 :            :  *
      29                 :            :  *  All parts contributed on or after August 2011:
      30                 :            :  *
      31                 :            :  *    Version: MPL 1.1 / GPLv3+ / LGPLv2.1+
      32                 :            :  *
      33                 :            :  *    The contents of this file are subject to the Mozilla Public License Version
      34                 :            :  *    1.1 (the "License"); you may not use this file except in compliance with
      35                 :            :  *    the License or as specified alternatively below. You may obtain a copy of
      36                 :            :  *    the License at http://www.mozilla.org/MPL/
      37                 :            :  *
      38                 :            :  *    Software distributed under the License is distributed on an "AS IS" basis,
      39                 :            :  *    WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      40                 :            :  *    for the specific language governing rights and limitations under the
      41                 :            :  *    License.
      42                 :            :  *
      43                 :            :  *    Major Contributor(s):
      44                 :            :  *    [ Copyright (C) 2011 Lionel Elie Mamane <lionel@mamane.lu> ]
      45                 :            :  *
      46                 :            :  *    All Rights Reserved.
      47                 :            :  *
      48                 :            :  *    For minor contributions see the git repository.
      49                 :            :  *
      50                 :            :  *    Alternatively, the contents of this file may be used under the terms of
      51                 :            :  *    either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      52                 :            :  *    the GNU Lesser General Public License Version 2.1 or later (the "LGPLv2.1+"),
      53                 :            :  *    in which case the provisions of the GPLv3+ or the LGPLv2.1+ are applicable
      54                 :            :  *    instead of those above.
      55                 :            :  *
      56                 :            :  *   Some portions were adapted from JDBC PostgreSQL driver:
      57                 :            :  *
      58                 :            :  *    Copyright (c) 2004-2008, PostgreSQL Global Development Group
      59                 :            :  *
      60                 :            :  *   Licence of original JDBC driver code:
      61                 :            :  *
      62                 :            :  *    Redistribution and use in source and binary forms, with or without
      63                 :            :  *    modification, are permitted provided that the following conditions are met:
      64                 :            :  *
      65                 :            :  *    1. Redistributions of source code must retain the above copyright notice,
      66                 :            :  *       this list of conditions and the following disclaimer.
      67                 :            :  *    2. Redistributions in binary form must reproduce the above copyright notice,
      68                 :            :  *       this list of conditions and the following disclaimer in the documentation
      69                 :            :  *       and/or other materials provided with the distribution.
      70                 :            :  *    3. Neither the name of the PostgreSQL Global Development Group nor the names
      71                 :            :  *       of its contributors may be used to endorse or promote products derived
      72                 :            :  *       from this software without specific prior written permission.
      73                 :            :  *
      74                 :            :  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      75                 :            :  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      76                 :            :  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      77                 :            :  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      78                 :            :  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      79                 :            :  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      80                 :            :  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      81                 :            :  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      82                 :            :  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      83                 :            :  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      84                 :            :  *    POSSIBILITY OF SUCH DAMAGE.
      85                 :            :  *
      86                 :            :  ************************************************************************/
      87                 :            : 
      88                 :            : #include <algorithm>
      89                 :            : #include "pq_databasemetadata.hxx"
      90                 :            : #include "pq_driver.hxx"
      91                 :            : #include "pq_sequenceresultset.hxx"
      92                 :            : #include "pq_statics.hxx"
      93                 :            : #include "pq_tools.hxx"
      94                 :            : 
      95                 :            : #include <rtl/ustrbuf.hxx>
      96                 :            : 
      97                 :            : #include<com/sun/star/sdbc/TransactionIsolation.hpp>
      98                 :            : #include<com/sun/star/sdbc/ResultSetType.hpp>
      99                 :            : #include<com/sun/star/sdbc/XPreparedStatement.hpp>
     100                 :            : #include<com/sun/star/sdbc/XParameters.hpp>
     101                 :            : #include<com/sun/star/sdbc/DataType.hpp>
     102                 :            : #include<com/sun/star/sdbc/IndexType.hpp>
     103                 :            : #include<com/sun/star/sdbc/ColumnValue.hpp>
     104                 :            : #include<com/sun/star/sdbc/ColumnSearch.hpp>
     105                 :            : #include<com/sun/star/sdbc/KeyRule.hpp>
     106                 :            : #include<com/sun/star/sdbc/Deferrability.hpp>
     107                 :            : 
     108                 :            : using ::osl::MutexGuard;
     109                 :            : 
     110                 :            : using ::rtl::OUString;
     111                 :            : 
     112                 :            : using namespace com::sun::star::sdbc;
     113                 :            : 
     114                 :            : using com::sun::star::uno::RuntimeException;
     115                 :            : using com::sun::star::uno::Sequence;
     116                 :            : 
     117                 :            : using com::sun::star::uno::Reference;
     118                 :            : using com::sun::star::uno::Sequence;
     119                 :            : using com::sun::star::uno::Any;
     120                 :            : using com::sun::star::uno::makeAny;
     121                 :            : using com::sun::star::uno::UNO_QUERY;
     122                 :            : using com::sun::star::uno::UNO_QUERY_THROW;
     123                 :            : 
     124                 :            : namespace pq_sdbc_driver
     125                 :            : {
     126                 :            : typedef
     127                 :            : std::vector
     128                 :            : <
     129                 :            :     com::sun::star::uno::Sequence< com::sun::star::uno::Any >,
     130                 :            :     Allocator< com::sun::star::uno::Sequence< com::sun::star::uno::Any > >
     131                 :            : > SequenceAnyVector;
     132                 :            : 
     133                 :            : 
     134                 :            : #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
     135                 :            : 
     136                 :            : #define QUOTEME(X)  #X
     137                 :            : #define STRINGIFY(X) QUOTEME(X)
     138                 :            : 
     139                 :            : // These are pre-processor versions of KeyRule.idl declarations
     140                 :            : // These are inherited from JDBC, and thus won't change anytime soon.
     141                 :            : // Having them as pre-processor definitions allows to include them
     142                 :            : // into compile-time strings (through STRINGIFY), which can be passed to ASCII_STR.
     143                 :            : // That is without resorting to horrendeous hacks in template meta-programming.
     144                 :            : #define KEYRULE_CASCADE      0
     145                 :            : #define KEYRULE_RESTRICT     1
     146                 :            : #define KEYRULE_SET_NULL     2
     147                 :            : #define KEYRULE_NO_ACTION    4
     148                 :            : #define KEYRULE_SET_DEFAULT  4
     149                 :            : // Ditto for Deferrability.idl
     150                 :            : #define DEFERRABILITY_INITIALLY_DEFERRED  5
     151                 :            : #define DEFERRABILITY_INITIALLY_IMMEDIATE 6
     152                 :            : #define DEFERRABILITY_NONE                7
     153                 :            : 
     154                 :            : // alphabetically ordered !
     155                 :            : static const int PRIVILEGE_CREATE     = 0x1;
     156                 :            : static const int PRIVILEGE_DELETE     = 0x2;
     157                 :            : static const int PRIVILEGE_EXECUTE    = 0x4;
     158                 :            : static const int PRIVILEGE_INSERT     = 0x8;
     159                 :            : static const int PRIVILEGE_REFERENCES = 0x10;
     160                 :            : static const int PRIVILEGE_RULE       = 0x20;
     161                 :            : static const int PRIVILEGE_SELECT     = 0x40;
     162                 :            : static const int PRIVILEGE_TEMPORARY  = 0x80;
     163                 :            : static const int PRIVILEGE_TRIGGER    = 0x100;
     164                 :            : static const int PRIVILEGE_UPDATE     = 0x200;
     165                 :            : static const int PRIVILEGE_USAGE      = 0x400;
     166                 :            : static const int PRIVILEGE_MAX = PRIVILEGE_USAGE;
     167                 :            : 
     168                 :          0 : void DatabaseMetaData::checkClosed()
     169                 :            :         throw (SQLException, RuntimeException)
     170                 :            : {
     171                 :          0 : }
     172                 :            : 
     173                 :          0 : DatabaseMetaData::DatabaseMetaData(
     174                 :            :     const ::rtl::Reference< RefCountedMutex > & refMutex,
     175                 :            :     const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection >  & origin,
     176                 :            :     ConnectionSettings *pSettings )
     177                 :            :   : m_refMutex( refMutex ),
     178                 :            :     m_pSettings( pSettings ),
     179                 :            :     m_origin( origin ),
     180                 :          0 :     m_getIntSetting_stmt ( m_origin->prepareStatement(ASCII_STR( "SELECT setting FROM pg_catalog.pg_settings WHERE name=?" )) )
     181                 :            : {
     182                 :          0 :     init_getReferences_stmt();
     183                 :          0 :     init_getPrivs_stmt();
     184                 :          0 : }
     185                 :            : 
     186                 :          0 : sal_Bool DatabaseMetaData::allProceduresAreCallable(  ) throw (SQLException, RuntimeException)
     187                 :            : {
     188                 :            :     // TODO
     189                 :          0 :     return sal_False;
     190                 :            : }
     191                 :            : 
     192                 :          0 : sal_Bool DatabaseMetaData::allTablesAreSelectable(  ) throw (SQLException, RuntimeException)
     193                 :            : {
     194                 :          0 :     return sal_True;
     195                 :            : }
     196                 :            : 
     197                 :          0 : OUString DatabaseMetaData::getURL(  ) throw (SQLException, RuntimeException)
     198                 :            : {
     199                 :            :     // TODO
     200                 :            :     // LEM TODO: implement
     201                 :          0 :     return OUString();
     202                 :            : }
     203                 :            : 
     204                 :          0 : OUString DatabaseMetaData::getUserName(  ) throw (SQLException, RuntimeException)
     205                 :            : {
     206                 :          0 :     return m_pSettings->user;
     207                 :            : }
     208                 :            : 
     209                 :          0 : sal_Bool DatabaseMetaData::isReadOnly(  ) throw (SQLException, RuntimeException)
     210                 :            : {
     211                 :          0 :     return sal_False;
     212                 :            : }
     213                 :            : 
     214                 :            : 
     215                 :          0 : sal_Bool DatabaseMetaData::nullsAreSortedHigh(  ) throw (SQLException, RuntimeException)
     216                 :            : {
     217                 :            :     // Whether NULL values are considered, for sorting purposes, LARGER than any other value.
     218                 :            :     // Specification: http://download.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#nullsAreSortedHigh()
     219                 :            :     // PostgreSQL behaviour: http://www.postgresql.org/docs/9.1/static/queries-order.htlm
     220                 :          0 :     return sal_True;
     221                 :            : }
     222                 :            : 
     223                 :          0 : sal_Bool DatabaseMetaData::nullsAreSortedLow(  ) throw (SQLException, RuntimeException)
     224                 :            : {
     225                 :          0 :     return ! nullsAreSortedHigh();
     226                 :            : }
     227                 :            : 
     228                 :          0 : sal_Bool DatabaseMetaData::nullsAreSortedAtStart(  ) throw (SQLException, RuntimeException)
     229                 :            : {
     230                 :          0 :     return sal_False;
     231                 :            : }
     232                 :            : 
     233                 :          0 : sal_Bool DatabaseMetaData::nullsAreSortedAtEnd(  ) throw (SQLException, RuntimeException)
     234                 :            : {
     235                 :          0 :     return sal_False;
     236                 :            : }
     237                 :            : 
     238                 :          0 : OUString DatabaseMetaData::getDatabaseProductName(  ) throw (SQLException, RuntimeException)
     239                 :            : {
     240                 :          0 :     return ASCII_STR("PostgreSQL");
     241                 :            : }
     242                 :            : 
     243                 :          0 : OUString DatabaseMetaData::getDatabaseProductVersion(  ) throw (SQLException, RuntimeException)
     244                 :            : {
     245                 :          0 :     return rtl::OUString::createFromAscii( PQparameterStatus( m_pSettings->pConnection, "server_version" ) );
     246                 :            : }
     247                 :          0 : OUString DatabaseMetaData::getDriverName(  ) throw (SQLException, RuntimeException)
     248                 :            : {
     249                 :          0 :     return ASCII_STR( "postgresql-sdbc" );
     250                 :            : }
     251                 :            : 
     252                 :          0 : OUString DatabaseMetaData::getDriverVersion(  ) throw (SQLException, RuntimeException)
     253                 :            : {
     254                 :          0 :     return ASCII_STR( PQ_SDBC_DRIVER_VERSION );
     255                 :            : }
     256                 :            : 
     257                 :          0 : sal_Int32 DatabaseMetaData::getDriverMajorVersion(  ) throw (RuntimeException)
     258                 :            : {
     259                 :          0 :     return PQ_SDBC_MAJOR;
     260                 :            : }
     261                 :            : 
     262                 :          0 : sal_Int32 DatabaseMetaData::getDriverMinorVersion(  ) throw (RuntimeException)
     263                 :            : {
     264                 :          0 :     return PQ_SDBC_MINOR;
     265                 :            : }
     266                 :            : 
     267                 :          0 : sal_Bool DatabaseMetaData::usesLocalFiles(  ) throw (SQLException, RuntimeException)
     268                 :            : {
     269                 :            :     // LEM TODO:
     270                 :            :     //           http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Database/XDatabaseMetaData_Interface
     271                 :            :     //           says "Returns true when the catalog name of the
     272                 :            :     //           database should not appear in the DatasourceBrowser
     273                 :            :     //           of OpenOffice.org API, otherwise false is returned."
     274                 :            :     //           So, hmmm, think about it.
     275                 :          0 :     return sal_False;
     276                 :            : }
     277                 :            : 
     278                 :          0 : sal_Bool DatabaseMetaData::usesLocalFilePerTable(  ) throw (SQLException, RuntimeException)
     279                 :            : {
     280                 :          0 :     return sal_False;
     281                 :            : }
     282                 :            : 
     283                 :          0 : sal_Bool DatabaseMetaData::supportsMixedCaseIdentifiers(  ) throw (SQLException, RuntimeException)
     284                 :            : {
     285                 :          0 :     return sal_False;
     286                 :            : }
     287                 :            : 
     288                 :          0 : sal_Bool DatabaseMetaData::storesUpperCaseIdentifiers(  ) throw (SQLException, RuntimeException)
     289                 :            : {
     290                 :          0 :     return sal_False;
     291                 :            : }
     292                 :            : 
     293                 :          0 : sal_Bool DatabaseMetaData::storesLowerCaseIdentifiers(  ) throw (SQLException, RuntimeException)
     294                 :            : {
     295                 :          0 :     return sal_True;
     296                 :            : }
     297                 :            : 
     298                 :            : 
     299                 :          0 : sal_Bool DatabaseMetaData::storesMixedCaseIdentifiers(  ) throw (SQLException, RuntimeException)
     300                 :            : {
     301                 :          0 :     return sal_False;
     302                 :            : }
     303                 :            : 
     304                 :            : 
     305                 :          0 : sal_Bool DatabaseMetaData::supportsMixedCaseQuotedIdentifiers(  ) throw (SQLException, RuntimeException)
     306                 :            : {
     307                 :          0 :     return sal_True;
     308                 :            : }
     309                 :            : 
     310                 :          0 : sal_Bool DatabaseMetaData::storesUpperCaseQuotedIdentifiers(  ) throw (SQLException, RuntimeException)
     311                 :            : {
     312                 :          0 :     return sal_False;
     313                 :            : }
     314                 :            : 
     315                 :            : 
     316                 :          0 : sal_Bool DatabaseMetaData::storesLowerCaseQuotedIdentifiers(  ) throw (SQLException, RuntimeException)
     317                 :            : {
     318                 :          0 :     return sal_False;
     319                 :            : }
     320                 :            : 
     321                 :            : 
     322                 :          0 : sal_Bool DatabaseMetaData::storesMixedCaseQuotedIdentifiers(  ) throw (SQLException, RuntimeException)
     323                 :            : {
     324                 :          0 :     return sal_False;
     325                 :            : }
     326                 :            : 
     327                 :            : 
     328                 :          0 : OUString DatabaseMetaData::getIdentifierQuoteString(  ) throw (SQLException, RuntimeException)
     329                 :            : {
     330                 :          0 :     return ASCII_STR( "\"" );
     331                 :            : }
     332                 :            : 
     333                 :          0 : OUString DatabaseMetaData::getSQLKeywords(  ) throw (SQLException, RuntimeException)
     334                 :            : {
     335                 :            :     // In Java 6, this is all keywords that are not SQL:2003
     336                 :            :     // In Java 2 v1.4 and as per LibreOffice SDK doc, this is all keywords that are not SQL92
     337                 :            :     // I understand this to mean "reserved keywords" only.
     338                 :            :     // See http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html
     339                 :          0 :     return ASCII_STR(
     340                 :            :         "ANALYSE,"
     341                 :            :         "ANALYZE,"
     342                 :            :         "ARRAY," //SQL:1999
     343                 :            :         "ASYMMETRIC," //SQL:2003
     344                 :            :         "BINARY," //SQL:1999
     345                 :            :         "CONCURRENTLY,"
     346                 :            :         "CURRENT_CATALOG," //SQL:2008
     347                 :            :         "CURRENT_ROLE," //SQL:1999
     348                 :            :         "CURRENT_SCHEMA," //SQL:2008
     349                 :            :         "DO,"
     350                 :            :         "FREEZE,"
     351                 :            :         "ILIKE,"
     352                 :            :         "ISNULL,"
     353                 :            :         "LIMIT," //SQL:1999; non-reserved in SQL:2003
     354                 :            :         "LOCALTIME," //SQL:1999
     355                 :            :         "LOCALTIMESTAMP," //SQL:1999
     356                 :            :         "NOTNULL,"
     357                 :            :         "OFFSET," //SQL:2008
     358                 :            :         "OVER," //SQL:2003
     359                 :            :         "PLACING," //non-reserved in SQL:2003
     360                 :            :         "RETURNING," //non-reserved in SQL:2008
     361                 :            :         "SIMILAR," //SQL:2003
     362                 :            :         "VARIADIC,"
     363                 :            :         "VERBOSE,"
     364                 :            :         "WINDOW" //SQL:2003
     365                 :            :  );
     366                 :            : }
     367                 :          0 : OUString DatabaseMetaData::getNumericFunctions(  ) throw (SQLException, RuntimeException)
     368                 :            : {
     369                 :            :     // See http://www.postgresql.org/docs/9.1/static/functions-math.html
     370                 :            :     // LEM TODO: Err... http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Database/Support_Scalar_Functions
     371                 :            :     //           says this should be "Open Group CLI" names, not PostgreSQL names.
     372                 :            :     //           Currently this is just a list of supported functions in PostgreSQL, with PostgreSQL names.
     373                 :            :     //           And it is my job to map from Open Group CLI names/syntax to PostgreSQL names/syntax. Where? By parsing the SQL???
     374                 :            :     //           Should look at what the JDBC driver is doing.
     375                 :          0 :     return ASCII_STR(
     376                 :            :         "abs,"
     377                 :            :         "cbrt,"
     378                 :            :         "ceil,"
     379                 :            :         "ceiling,"
     380                 :            :         "degrees,"
     381                 :            :         "div,"
     382                 :            :         "exp,"
     383                 :            :         "floor,"
     384                 :            :         "ln,"
     385                 :            :         "log,"
     386                 :            :         "mod,"
     387                 :            :         "pi,"
     388                 :            :         "power,"
     389                 :            :         "radians,"
     390                 :            :         "random,"
     391                 :            :         "round,"
     392                 :            :         "setseed,"
     393                 :            :         "sign,"
     394                 :            :         "sqrt,"
     395                 :            :         "trunc,"
     396                 :            :         "width_bucket,"
     397                 :            :         "acos,"
     398                 :            :         "asin,"
     399                 :            :         "atan,"
     400                 :            :         "atan2,"
     401                 :            :         "cos,"
     402                 :            :         "cot,"
     403                 :            :         "sin,"
     404                 :            :         "tan"
     405                 :            :  );
     406                 :            : }
     407                 :            : 
     408                 :          0 : OUString DatabaseMetaData::getStringFunctions(  ) throw (SQLException, RuntimeException)
     409                 :            : {
     410                 :            :     // See http://www.postgresql.org/docs/9.1/static/functions-string.html
     411                 :          0 :     return ASCII_STR(
     412                 :            :         "bit_length,"
     413                 :            :         "char_length,"
     414                 :            :         "character_length,"
     415                 :            :         "lower,"
     416                 :            :         "octet_length,"
     417                 :            :         "overlay,"
     418                 :            :         "position,"
     419                 :            :         "substring,"
     420                 :            :         "trim,"
     421                 :            :         "upper,"
     422                 :            :         "ascii,"
     423                 :            :         "btrim,"
     424                 :            :         "chr,"
     425                 :            :         "concat,"
     426                 :            :         "concat_ws,"
     427                 :            :         "convert,"
     428                 :            :         "convert_from,"
     429                 :            :         "convert_to,"
     430                 :            :         "decode,"
     431                 :            :         "encode,"
     432                 :            :         "foramt,"
     433                 :            :         "initcap,"
     434                 :            :         "left,"
     435                 :            :         "length,"
     436                 :            :         "lpad,"
     437                 :            :         "ltrim,"
     438                 :            :         "md5,"
     439                 :            :         "pg_client_encoding,"
     440                 :            :         "quote_ident,"
     441                 :            :         "quote_literal,"
     442                 :            :         "quote_nullable,"
     443                 :            :         "regexp_matches,"
     444                 :            :         "regexp_replace,"
     445                 :            :         "regexp_split_to_array,"
     446                 :            :         "regexp_split_to_table,"
     447                 :            :         "repeat,"
     448                 :            :         "replace,"
     449                 :            :         "reverse,"
     450                 :            :         "right,"
     451                 :            :         "rpad,"
     452                 :            :         "rtrim,"
     453                 :            :         "split_part,"
     454                 :            :         "strpos,"
     455                 :            :         "substr,"
     456                 :            :         "to_ascii,"
     457                 :            :         "to_hex,"
     458                 :            :         "translate"
     459                 :            :  );
     460                 :            : }
     461                 :            : 
     462                 :          0 : OUString DatabaseMetaData::getSystemFunctions(  ) throw (SQLException, RuntimeException)
     463                 :            : {
     464                 :            :     // See http://www.postgresql.org/docs/9.1/static/functions-info.html
     465                 :            :     // and http://www.postgresql.org/docs/9.1/static/functions-admin.html
     466                 :          0 :     return ASCII_STR(
     467                 :            :         "current_catalog,"
     468                 :            :         "current_database,"
     469                 :            :         "current_query,"
     470                 :            :         "current_schema,"
     471                 :            :         "current_schemas,"
     472                 :            :         "current_user,"
     473                 :            :         "inet_client_addr,"
     474                 :            :         "inet_client_port,"
     475                 :            :         "inet_server_addr,"
     476                 :            :         "inet_server_port,"
     477                 :            :         "pg_backend_pid,"
     478                 :            :         "pg_conf_load_time,"
     479                 :            :         "pg_is_other_temp_schema,"
     480                 :            :         "pg_listening_channels,"
     481                 :            :         "pg_my_temp_schema,"
     482                 :            :         "pg_postmaster_start_time,"
     483                 :            :         "session_user,"
     484                 :            :         "user,"
     485                 :            :         "version,"
     486                 :            :         "has_any_column_privilege,"
     487                 :            :         "has_any_column_privilege,"
     488                 :            :         "has_any_column_privilege,"
     489                 :            :         "has_column_privilege,"
     490                 :            :         "has_database_privilege,"
     491                 :            :         "has_foreign_data_wrapper_privilege,"
     492                 :            :         "has_function_privilege,"
     493                 :            :         "has_language_privilege,"
     494                 :            :         "has_schema_privilege,"
     495                 :            :         "has_sequence_privilege,"
     496                 :            :         "has_server_privilege,"
     497                 :            :         "has_table_privilege,"
     498                 :            :         "has_tablespace_privilege,"
     499                 :            :         "pg_has_role,"
     500                 :            :         "pg_collation_is_visible,"
     501                 :            :         "pg_conversion_is_visible,"
     502                 :            :         "pg_function_is_visible,"
     503                 :            :         "pg_opclass_is_visible,"
     504                 :            :         "pg_operator_is_visible,"
     505                 :            :         "pg_table_is_visible,"
     506                 :            :         "pg_ts_config_is_visible,"
     507                 :            :         "pg_ts_dict_is_visible,"
     508                 :            :         "pg_ts_parser_is_visible,"
     509                 :            :         "pg_ts_template_is_visible,"
     510                 :            :         "pg_type_is_visible,"
     511                 :            :         "format_type,"
     512                 :            :         "pg_describe_object,"
     513                 :            :         "pg_get_constraintdef,"
     514                 :            :         "pg_get_expr,"
     515                 :            :         "pg_get_functiondef,"
     516                 :            :         "pg_get_function_arguments,"
     517                 :            :         "pg_get_function_identity_arguments,"
     518                 :            :         "pg_get_function_result,"
     519                 :            :         "pg_get_indexdef,"
     520                 :            :         "pg_get_keywords,"
     521                 :            :         "pg_get_ruledef,"
     522                 :            :         "pg_get_serial_sequence,"
     523                 :            :         "pg_get_triggerdef,"
     524                 :            :         "pg_get_userbyid,"
     525                 :            :         "pg_get_viewdef,"
     526                 :            :         "pg_options_to_table,"
     527                 :            :         "pg_tablespace_databases,"
     528                 :            :         "pg_typeof,"
     529                 :            :         "col_description,"
     530                 :            :         "obj_description,"
     531                 :            :         "shobj_description,"
     532                 :            :         "txid_current,"
     533                 :            :         "txid_current_snapshot,"
     534                 :            :         "txid_snapshot_xip,"
     535                 :            :         "txid_snapshot_xmax,"
     536                 :            :         "txid_snapshot_xmin,"
     537                 :            :         "txid_visible_in_snapshot,"
     538                 :            :         "xmin,"
     539                 :            :         "xmax,"
     540                 :            :         "xip_list,"
     541                 :            :         "current_setting,"
     542                 :            :         "set_config,"
     543                 :            :         "pg_cancel_backend,"
     544                 :            :         "pg_reload_conf,"
     545                 :            :         "pg_rotate_logfile,"
     546                 :            :         "pg_terminate_backend,"
     547                 :            :         "pg_create_restore_point,"
     548                 :            :         "pg_current_xlog_insert_location,"
     549                 :            :         "pg_current_xlog_location,"
     550                 :            :         "pg_start_backup,"
     551                 :            :         "pg_stop_backup,"
     552                 :            :         "pg_switch_xlog,"
     553                 :            :         "pg_xlogfile_name,"
     554                 :            :         "pg_xlogfile_name_offset,"
     555                 :            :         "pg_is_in_recovery,"
     556                 :            :         "pg_last_xlog_receive_location,"
     557                 :            :         "pg_last_xlog_replay_location,"
     558                 :            :         "pg_last_xact_replay_timestamp,"
     559                 :            :         "pg_is_xlog_replay_paused,"
     560                 :            :         "pg_xlog_replay_pause,"
     561                 :            :         "pg_xlog_replay_resume,"
     562                 :            :         "pg_column_size,"
     563                 :            :         "pg_database_size,"
     564                 :            :         "pg_indexes_size,"
     565                 :            :         "pg_relation_size,"
     566                 :            :         "pg_size_pretty,"
     567                 :            :         "pg_table_size,"
     568                 :            :         "pg_tablespace_size,"
     569                 :            :         "pg_tablespace_size,"
     570                 :            :         "pg_total_relation_size,"
     571                 :            :         "pg_relation_filenode,"
     572                 :            :         "pg_relation_filepath,"
     573                 :            :         "pg_ls_dir,"
     574                 :            :         "pg_read_file,"
     575                 :            :         "pg_read_binary_file,"
     576                 :            :         "pg_stat_file,"
     577                 :            :         "pg_advisory_lock,"
     578                 :            :         "pg_advisory_lock_shared,"
     579                 :            :         "pg_advisory_unlock,"
     580                 :            :         "pg_advisory_unlock_all,"
     581                 :            :         "pg_advisory_unlock_shared,"
     582                 :            :         "pg_advisory_xact_lock,"
     583                 :            :         "pg_advisory_xact_lock_shared,"
     584                 :            :         "pg_try_advisory_lock,"
     585                 :            :         "pg_try_advisory_lock_shared,"
     586                 :            :         "pg_try_advisory_xact_lock,"
     587                 :            :         "pg_try_advisory_xact_lock_shared,"
     588                 :            :         "pg_sleep"
     589                 :            :  );
     590                 :            : }
     591                 :          0 : OUString DatabaseMetaData::getTimeDateFunctions(  ) throw (SQLException, RuntimeException)
     592                 :            : {
     593                 :            :     // TODO
     594                 :          0 :     return ASCII_STR(
     595                 :            :         "age,"
     596                 :            :         "age,"
     597                 :            :         "clock_timestamp,"
     598                 :            :         "current_date,"
     599                 :            :         "current_time,"
     600                 :            :         "current_timestamp,"
     601                 :            :         "date_part,"
     602                 :            :         "date_part,"
     603                 :            :         "date_trunc,"
     604                 :            :         "extract,"
     605                 :            :         "extract,"
     606                 :            :         "isfinite,"
     607                 :            :         "isfinite,"
     608                 :            :         "isfinite,"
     609                 :            :         "justify_days,"
     610                 :            :         "justify_hours,"
     611                 :            :         "justify_interval,"
     612                 :            :         "localtime,"
     613                 :            :         "localtimestamp,"
     614                 :            :         "now,"
     615                 :            :         "statement_timestamp,"
     616                 :            :         "timeofday,"
     617                 :            :         "transaction_timestamp,"
     618                 :            :  );
     619                 :            : }
     620                 :          0 : OUString DatabaseMetaData::getSearchStringEscape(  ) throw (SQLException, RuntimeException)
     621                 :            : {
     622                 :          0 :     return ASCII_STR( "\\" );
     623                 :            : }
     624                 :          0 : OUString DatabaseMetaData::getExtraNameCharacters(  ) throw (SQLException, RuntimeException)
     625                 :            : {
     626                 :          0 :     return ASCII_STR( "$" );
     627                 :            : }
     628                 :            : 
     629                 :          0 : sal_Bool DatabaseMetaData::supportsAlterTableWithAddColumn(  ) throw (SQLException, RuntimeException)
     630                 :            : {
     631                 :          0 :     return sal_True;
     632                 :            : }
     633                 :            : 
     634                 :          0 : sal_Bool DatabaseMetaData::supportsAlterTableWithDropColumn(  ) throw (SQLException, RuntimeException)
     635                 :            : {
     636                 :          0 :     return sal_True;
     637                 :            : }
     638                 :            : 
     639                 :          0 : sal_Bool DatabaseMetaData::supportsColumnAliasing(  ) throw (SQLException, RuntimeException)
     640                 :            : {
     641                 :          0 :     return sal_True;
     642                 :            : }
     643                 :            : 
     644                 :          0 : sal_Bool DatabaseMetaData::nullPlusNonNullIsNull(  ) throw (SQLException, RuntimeException)
     645                 :            : {
     646                 :          0 :     return sal_True;
     647                 :            : }
     648                 :            : 
     649                 :          0 : sal_Bool DatabaseMetaData::supportsTypeConversion(  ) throw (SQLException, RuntimeException)
     650                 :            : {
     651                 :            :     // LEM: this is specifically whether the "CONVERT" function is supported
     652                 :            :     //      It seems that in PostgreSQL, that function is only for string encoding, so no.
     653                 :          0 :     return sal_False;
     654                 :            : }
     655                 :            : 
     656                 :          0 : sal_Bool DatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_Int32 toType ) throw (SQLException, RuntimeException)
     657                 :            : {
     658                 :            :     (void) fromType; (void) toType;
     659                 :          0 :     return sal_False;
     660                 :            : }
     661                 :            : 
     662                 :          0 : sal_Bool DatabaseMetaData::supportsTableCorrelationNames(  ) throw (SQLException, RuntimeException)
     663                 :            : {
     664                 :            :     // LEM: A correlation name is "bar" in "SELECT foo FROM qux [AS] bar WHERE ..."
     665                 :          0 :     return sal_True;
     666                 :            : }
     667                 :            : 
     668                 :            : 
     669                 :          0 : sal_Bool DatabaseMetaData::supportsDifferentTableCorrelationNames(  ) throw (SQLException, RuntimeException)
     670                 :            : {
     671                 :          0 :     return sal_False;
     672                 :            : }
     673                 :          0 : sal_Bool DatabaseMetaData::supportsExpressionsInOrderBy(  ) throw (SQLException, RuntimeException)
     674                 :            : {
     675                 :          0 :     return sal_True;
     676                 :            : }
     677                 :            : 
     678                 :          0 : sal_Bool DatabaseMetaData::supportsOrderByUnrelated(  ) throw (SQLException, RuntimeException)
     679                 :            : {
     680                 :          0 :     return sal_True;
     681                 :            : }
     682                 :            : 
     683                 :          0 : sal_Bool DatabaseMetaData::supportsGroupBy(  ) throw (SQLException, RuntimeException)
     684                 :            : {
     685                 :          0 :     return sal_True;
     686                 :            : }
     687                 :            : 
     688                 :          0 : sal_Bool DatabaseMetaData::supportsGroupByUnrelated(  ) throw (SQLException, RuntimeException)
     689                 :            : {
     690                 :          0 :     return sal_True;
     691                 :            : }
     692                 :            : 
     693                 :          0 : sal_Bool DatabaseMetaData::supportsGroupByBeyondSelect(  ) throw (SQLException, RuntimeException)
     694                 :            : {
     695                 :          0 :     return sal_True;
     696                 :            : }
     697                 :            : 
     698                 :          0 : sal_Bool DatabaseMetaData::supportsLikeEscapeClause(  ) throw (SQLException, RuntimeException)
     699                 :            : {
     700                 :          0 :     return sal_True;
     701                 :            : }
     702                 :            : 
     703                 :          0 : sal_Bool DatabaseMetaData::supportsMultipleResultSets(  ) throw (SQLException, RuntimeException)
     704                 :            : {
     705                 :          0 :     return sal_True;
     706                 :            : }
     707                 :            : 
     708                 :          0 : sal_Bool DatabaseMetaData::supportsMultipleTransactions(  ) throw (SQLException, RuntimeException)
     709                 :            : {
     710                 :            :     // Allows multiple transactions open at once (on different connections!)
     711                 :          0 :     return sal_True;
     712                 :            : }
     713                 :            : 
     714                 :          0 : sal_Bool DatabaseMetaData::supportsNonNullableColumns(  ) throw (SQLException, RuntimeException)
     715                 :            : {
     716                 :          0 :     return sal_True;
     717                 :            : }
     718                 :            : 
     719                 :            : 
     720                 :          0 : sal_Bool DatabaseMetaData::supportsMinimumSQLGrammar(  ) throw (SQLException, RuntimeException)
     721                 :            : {
     722                 :          0 :     return sal_True;
     723                 :            : }
     724                 :            : 
     725                 :          0 : sal_Bool DatabaseMetaData::supportsCoreSQLGrammar(  ) throw (SQLException, RuntimeException)
     726                 :            : {
     727                 :            :     // LEM: jdbc driver says not, although the comments in it seem old
     728                 :            :     //      fdo#45249 Base query design won't use any aggregate function
     729                 :            :     //      (except COUNT(*) unless we say yes, so say yes.
     730                 :            :     //      Actually, Base assumes *also* support for aggregate functions "collect, fusion, intersection"
     731                 :            :     //      as soon as supportsCoreSQLGrammar() returns true.
     732                 :            :     //      Those are *not* Core SQL, though. They are in optional feature S271 "Basic multiset support"
     733                 :          0 :     return sal_True;
     734                 :            : }
     735                 :            : 
     736                 :          0 : sal_Bool DatabaseMetaData::supportsExtendedSQLGrammar(  ) throw (SQLException, RuntimeException)
     737                 :            : {
     738                 :          0 :     return sal_False;
     739                 :            : }
     740                 :            : 
     741                 :          0 : sal_Bool DatabaseMetaData::supportsANSI92EntryLevelSQL(  ) throw (SQLException, RuntimeException)
     742                 :            : {
     743                 :          0 :     return sal_True;
     744                 :            : }
     745                 :            : 
     746                 :          0 : sal_Bool DatabaseMetaData::supportsANSI92IntermediateSQL(  ) throw (SQLException, RuntimeException)
     747                 :            : {
     748                 :            :     // LEM: jdbc driver says not, although the comments in it seem old
     749                 :          0 :     return sal_False;
     750                 :            : }
     751                 :            : 
     752                 :          0 : sal_Bool DatabaseMetaData::supportsANSI92FullSQL(  ) throw (SQLException, RuntimeException)
     753                 :            : {
     754                 :            :     // LEM: jdbc driver says not, although the comments in it seem old
     755                 :          0 :     return sal_False;
     756                 :            : }
     757                 :            : 
     758                 :          0 : sal_Bool DatabaseMetaData::supportsIntegrityEnhancementFacility(  ) throw (SQLException, RuntimeException)
     759                 :            : {
     760                 :            :     // LEM: jdbc driver says yes, although comment says they are not sure what this means...
     761                 :          0 :     return sal_True;
     762                 :            : }
     763                 :            : 
     764                 :          0 : sal_Bool DatabaseMetaData::supportsOuterJoins(  ) throw (SQLException, RuntimeException)
     765                 :            : {
     766                 :          0 :     return sal_True;
     767                 :            : }
     768                 :            : 
     769                 :          0 : sal_Bool DatabaseMetaData::supportsFullOuterJoins(  ) throw (SQLException, RuntimeException)
     770                 :            : {
     771                 :          0 :     return sal_True;
     772                 :            : }
     773                 :            : 
     774                 :          0 : sal_Bool DatabaseMetaData::supportsLimitedOuterJoins(  ) throw (SQLException, RuntimeException)
     775                 :            : {
     776                 :          0 :     return sal_True;
     777                 :            : }
     778                 :            : 
     779                 :            : 
     780                 :          0 : OUString DatabaseMetaData::getSchemaTerm(  ) throw (SQLException, RuntimeException)
     781                 :            : {
     782                 :          0 :     return ASCII_STR( "SCHEMA" );
     783                 :            : }
     784                 :            : 
     785                 :          0 : OUString DatabaseMetaData::getProcedureTerm(  ) throw (SQLException, RuntimeException)
     786                 :            : {
     787                 :          0 :     return ASCII_STR( "function" );
     788                 :            : }
     789                 :            : 
     790                 :          0 : OUString DatabaseMetaData::getCatalogTerm(  ) throw (SQLException, RuntimeException)
     791                 :            : {
     792                 :          0 :     return ASCII_STR( "DATABASE" );
     793                 :            : }
     794                 :            : 
     795                 :          0 : sal_Bool DatabaseMetaData::isCatalogAtStart(  ) throw (SQLException, RuntimeException)
     796                 :            : {
     797                 :            : 
     798                 :          0 :     return sal_True;
     799                 :            : }
     800                 :            : 
     801                 :          0 : OUString DatabaseMetaData::getCatalogSeparator(  ) throw (SQLException, RuntimeException)
     802                 :            : {
     803                 :          0 :     return ASCII_STR( "." );
     804                 :            : }
     805                 :            : 
     806                 :          0 : sal_Bool DatabaseMetaData::supportsSchemasInDataManipulation(  ) throw (SQLException, RuntimeException)
     807                 :            : {
     808                 :          0 :     return sal_True;
     809                 :            : }
     810                 :            : 
     811                 :          0 : sal_Bool DatabaseMetaData::supportsSchemasInProcedureCalls(  ) throw (SQLException, RuntimeException)
     812                 :            : {
     813                 :          0 :     return sal_True;
     814                 :            : }
     815                 :            : 
     816                 :          0 : sal_Bool DatabaseMetaData::supportsSchemasInTableDefinitions(  ) throw (SQLException, RuntimeException)
     817                 :            : {
     818                 :          0 :     return sal_True;
     819                 :            : }
     820                 :            : 
     821                 :          0 : sal_Bool DatabaseMetaData::supportsSchemasInIndexDefinitions(  ) throw (SQLException, RuntimeException)
     822                 :            : {
     823                 :          0 :     return sal_True;
     824                 :            : }
     825                 :            : 
     826                 :          0 : sal_Bool DatabaseMetaData::supportsSchemasInPrivilegeDefinitions(  ) throw (SQLException, RuntimeException)
     827                 :            : {
     828                 :          0 :     return sal_True;
     829                 :            : }
     830                 :            : 
     831                 :          0 : sal_Bool DatabaseMetaData::supportsCatalogsInDataManipulation(  ) throw (SQLException, RuntimeException)
     832                 :            : {
     833                 :          0 :     return sal_False;
     834                 :            : }
     835                 :            : 
     836                 :          0 : sal_Bool DatabaseMetaData::supportsCatalogsInProcedureCalls(  ) throw (SQLException, RuntimeException)
     837                 :            : {
     838                 :          0 :     return sal_False;
     839                 :            : }
     840                 :            : 
     841                 :          0 : sal_Bool DatabaseMetaData::supportsCatalogsInTableDefinitions(  ) throw (SQLException, RuntimeException)
     842                 :            : {
     843                 :          0 :     return sal_False;
     844                 :            : }
     845                 :            : 
     846                 :            : 
     847                 :          0 : sal_Bool DatabaseMetaData::supportsCatalogsInIndexDefinitions(  ) throw (SQLException, RuntimeException)
     848                 :            : {
     849                 :          0 :     return sal_False;
     850                 :            : }
     851                 :            : 
     852                 :            : 
     853                 :          0 : sal_Bool DatabaseMetaData::supportsCatalogsInPrivilegeDefinitions(  ) throw (SQLException, RuntimeException)
     854                 :            : {
     855                 :          0 :     return sal_False;
     856                 :            : }
     857                 :            : 
     858                 :            : 
     859                 :            : // LEM TODO: positioned (through cursor) updates and deletes seem
     860                 :            : // to be supported; see {UPDATE,DELETE} /table/ (...) WHERE CURRENT OF /cursor_name/" syntax
     861                 :            : // and http://www.postgresql.org/docs/9.1/static/view-pg-cursors.html
     862                 :            : // http://www.postgresql.org/docs/9.1/static/libpq-example.html actually uses a cursor :)
     863                 :          0 : sal_Bool DatabaseMetaData::supportsPositionedDelete(  ) throw (SQLException, RuntimeException)
     864                 :            : {
     865                 :            :     // LEM: jdbc driver says not, although the comments in it seem old
     866                 :          0 :     return sal_False;
     867                 :            : }
     868                 :            : 
     869                 :          0 : sal_Bool DatabaseMetaData::supportsPositionedUpdate(  ) throw (SQLException, RuntimeException)
     870                 :            : {
     871                 :            :     // LEM: jdbc driver says not, although the comments in it seem old
     872                 :          0 :     return sal_False;
     873                 :            : }
     874                 :            : 
     875                 :            : 
     876                 :          0 : sal_Bool DatabaseMetaData::supportsSelectForUpdate(  ) throw (SQLException, RuntimeException)
     877                 :            : {
     878                 :          0 :     return sal_True;
     879                 :            : }
     880                 :            : 
     881                 :            : 
     882                 :          0 : sal_Bool DatabaseMetaData::supportsStoredProcedures(  ) throw (SQLException, RuntimeException)
     883                 :            : {
     884                 :          0 :     return sal_True;
     885                 :            : }
     886                 :            : 
     887                 :            : 
     888                 :          0 : sal_Bool DatabaseMetaData::supportsSubqueriesInComparisons(  ) throw (SQLException, RuntimeException)
     889                 :            : {
     890                 :          0 :     return sal_True;
     891                 :            : }
     892                 :            : 
     893                 :          0 : sal_Bool DatabaseMetaData::supportsSubqueriesInExists(  ) throw (SQLException, RuntimeException)
     894                 :            : {
     895                 :          0 :     return sal_True;
     896                 :            : }
     897                 :            : 
     898                 :          0 : sal_Bool DatabaseMetaData::supportsSubqueriesInIns(  ) throw (SQLException, RuntimeException)
     899                 :            : {
     900                 :          0 :     return sal_True;
     901                 :            : }
     902                 :            : 
     903                 :          0 : sal_Bool DatabaseMetaData::supportsSubqueriesInQuantifieds(  ) throw (SQLException, RuntimeException)
     904                 :            : {
     905                 :            :     // LEM: jdbc driver says yes, although comment says they don't know what this means...
     906                 :          0 :     return sal_True;
     907                 :            : }
     908                 :            : 
     909                 :          0 : sal_Bool DatabaseMetaData::supportsCorrelatedSubqueries(  ) throw (SQLException, RuntimeException)
     910                 :            : {
     911                 :          0 :     return sal_True;
     912                 :            : }
     913                 :          0 : sal_Bool DatabaseMetaData::supportsUnion(  ) throw (SQLException, RuntimeException)
     914                 :            : {
     915                 :          0 :     return sal_True;
     916                 :            : }
     917                 :            : 
     918                 :          0 : sal_Bool DatabaseMetaData::supportsUnionAll(  ) throw (SQLException, RuntimeException)
     919                 :            : {
     920                 :          0 :     return sal_True;
     921                 :            : }
     922                 :            : 
     923                 :          0 : sal_Bool DatabaseMetaData::supportsOpenCursorsAcrossCommit(  ) throw (SQLException, RuntimeException)
     924                 :            : {
     925                 :          0 :     return sal_False;
     926                 :            : }
     927                 :            : 
     928                 :          0 : sal_Bool DatabaseMetaData::supportsOpenCursorsAcrossRollback(  ) throw (SQLException, RuntimeException)
     929                 :            : {
     930                 :          0 :     return sal_False;
     931                 :            : }
     932                 :            : 
     933                 :          0 : sal_Bool DatabaseMetaData::supportsOpenStatementsAcrossCommit(  ) throw (SQLException, RuntimeException)
     934                 :            : {
     935                 :          0 :     return sal_True;
     936                 :            : }
     937                 :          0 : sal_Bool DatabaseMetaData::supportsOpenStatementsAcrossRollback(  ) throw (SQLException, RuntimeException)
     938                 :            : {
     939                 :          0 :     return sal_True;
     940                 :            : }
     941                 :            : 
     942                 :          0 : sal_Int32 DatabaseMetaData::getMaxBinaryLiteralLength(  ) throw (SQLException, RuntimeException)
     943                 :            : {
     944                 :          0 :     return 0;
     945                 :            : }
     946                 :            : 
     947                 :          0 : sal_Int32 DatabaseMetaData::getMaxCharLiteralLength(  ) throw (SQLException, RuntimeException)
     948                 :            : {
     949                 :          0 :     return 0;
     950                 :            : }
     951                 :            : 
     952                 :            : // Copied / adapted / simplified from JDBC driver
     953                 :          0 : sal_Int32 DatabaseMetaData::getIntSetting(OUString settingName)
     954                 :            :     throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
     955                 :            : {
     956                 :          0 :     MutexGuard guard( m_refMutex->mutex );
     957                 :            : 
     958                 :          0 :     Reference< XParameters > params(m_getIntSetting_stmt, UNO_QUERY_THROW );
     959                 :          0 :     params->setString(1, settingName );
     960                 :          0 :     Reference< XResultSet > rs = m_getIntSetting_stmt->executeQuery();
     961                 :          0 :     Reference< XRow > xRow( rs , UNO_QUERY_THROW );
     962                 :          0 :     OSL_VERIFY(rs->next());
     963                 :            :     OSL_ENSURE(rs->isFirst(), "postgresql-sdbc DatabaseMetaData getIntSetting not on first row");
     964                 :            :     OSL_ENSURE(rs->isLast(),  "postgresql-sdbc DatabaseMetaData getIntSetting not on last row");
     965                 :          0 :     return xRow->getInt(1);
     966                 :            : }
     967                 :            : 
     968                 :          0 : sal_Int32 DatabaseMetaData::getMaxNameLength()
     969                 :            :     throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
     970                 :            : {
     971                 :          0 :     if ( m_pSettings->maxNameLen == 0)
     972                 :          0 :         m_pSettings->maxNameLen = getIntSetting( ASCII_STR("max_identifier_length") );
     973                 :            :     OSL_ENSURE(m_pSettings->maxNameLen, "postgresql-sdbc: maxNameLen is zero");
     974                 :          0 :     return m_pSettings->maxNameLen;
     975                 :            : }
     976                 :            : 
     977                 :          0 : sal_Int32 DatabaseMetaData::getMaxIndexKeys()
     978                 :            :     throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
     979                 :            : {
     980                 :          0 :     if ( m_pSettings->maxIndexKeys == 0)
     981                 :          0 :         m_pSettings->maxIndexKeys = getIntSetting(ASCII_STR("max_index_keys"));
     982                 :            :     OSL_ENSURE(m_pSettings->maxIndexKeys, "postgresql-sdbc: maxIndexKeys is zero");
     983                 :          0 :     return m_pSettings->maxIndexKeys;
     984                 :            : }
     985                 :            : 
     986                 :          0 : sal_Int32 DatabaseMetaData::getMaxColumnNameLength(  ) throw (SQLException, RuntimeException)
     987                 :            : {
     988                 :          0 :     return getMaxNameLength();
     989                 :            : }
     990                 :            : 
     991                 :          0 : sal_Int32 DatabaseMetaData::getMaxColumnsInGroupBy(  ) throw (SQLException, RuntimeException)
     992                 :            : {
     993                 :          0 :     return 0;
     994                 :            : }
     995                 :            : 
     996                 :          0 : sal_Int32 DatabaseMetaData::getMaxColumnsInIndex(  ) throw (SQLException, RuntimeException)
     997                 :            : {
     998                 :          0 :     return getMaxIndexKeys();
     999                 :            : }
    1000                 :            : 
    1001                 :          0 : sal_Int32 DatabaseMetaData::getMaxColumnsInOrderBy(  ) throw (SQLException, RuntimeException)
    1002                 :            : {
    1003                 :          0 :     return 0;
    1004                 :            : }
    1005                 :            : 
    1006                 :          0 : sal_Int32 DatabaseMetaData::getMaxColumnsInSelect(  ) throw (SQLException, RuntimeException)
    1007                 :            : {
    1008                 :          0 :     return 0;
    1009                 :            : }
    1010                 :            : 
    1011                 :          0 : sal_Int32 DatabaseMetaData::getMaxColumnsInTable(  ) throw (SQLException, RuntimeException)
    1012                 :            : {
    1013                 :          0 :     return 1600;
    1014                 :            : }
    1015                 :            : 
    1016                 :          0 : sal_Int32 DatabaseMetaData::getMaxConnections(  ) throw (SQLException, RuntimeException)
    1017                 :            : {
    1018                 :            :     // LEM: The JDBC driver returns an arbitrary 8192; truth is as much as OS / hardware supports
    1019                 :          0 :     return 0;
    1020                 :            : }
    1021                 :            : 
    1022                 :          0 : sal_Int32 DatabaseMetaData::getMaxCursorNameLength(  ) throw (SQLException, RuntimeException) //TODO, don't know
    1023                 :            : {
    1024                 :          0 :     return getMaxNameLength();
    1025                 :            : }
    1026                 :            : 
    1027                 :          0 : sal_Int32 DatabaseMetaData::getMaxIndexLength(  ) throw (SQLException, RuntimeException) //TODO, don't know
    1028                 :            : {
    1029                 :            :     // LEM: that's the index itself, not its name
    1030                 :          0 :     return 0;
    1031                 :            : }
    1032                 :            : 
    1033                 :          0 : sal_Int32 DatabaseMetaData::getMaxSchemaNameLength(  ) throw (SQLException, RuntimeException)
    1034                 :            : {
    1035                 :          0 :     return getMaxNameLength();
    1036                 :            : }
    1037                 :            : 
    1038                 :          0 : sal_Int32 DatabaseMetaData::getMaxProcedureNameLength(  ) throw (SQLException, RuntimeException)
    1039                 :            : {
    1040                 :          0 :     return getMaxNameLength();
    1041                 :            : }
    1042                 :            : 
    1043                 :          0 : sal_Int32 DatabaseMetaData::getMaxCatalogNameLength(  ) throw (SQLException, RuntimeException)
    1044                 :            : {
    1045                 :          0 :     return getMaxNameLength();
    1046                 :            : }
    1047                 :            : 
    1048                 :          0 : sal_Int32 DatabaseMetaData::getMaxRowSize(  ) throw (SQLException, RuntimeException)
    1049                 :            : {
    1050                 :            :     // jdbc driver says 1GB, but http://www.postgresql.org/about/ says 1.6TB
    1051                 :            :     // and that 1GB is the maximum _field_ size
    1052                 :            :     // The row limit does not fit into a sal_Int32
    1053                 :          0 :     return 0;
    1054                 :            : }
    1055                 :            : 
    1056                 :          0 : sal_Bool DatabaseMetaData::doesMaxRowSizeIncludeBlobs(  ) throw (SQLException, RuntimeException)
    1057                 :            : {
    1058                 :            :     // LEM: Err... PostgreSQL basically does not do BLOBs well
    1059                 :            :     //      In any case, BLOBs do not change the maximal row length AFAIK
    1060                 :          0 :     return sal_True;
    1061                 :            : }
    1062                 :            : 
    1063                 :          0 : sal_Int32 DatabaseMetaData::getMaxStatementLength(  ) throw (SQLException, RuntimeException)
    1064                 :            : {
    1065                 :            :     // LEM: actually, that would be 2^sizeof(size_t)-1
    1066                 :            :     //      on the server? on the client (because of libpq)? minimum of the two? not sure
    1067                 :            :     //      Anyway, big, so say unlimited.
    1068                 :          0 :     return 0;
    1069                 :            : }
    1070                 :            : 
    1071                 :          0 : sal_Int32 DatabaseMetaData::getMaxStatements(  ) throw (SQLException, RuntimeException) //TODO, don't know
    1072                 :            : {
    1073                 :          0 :     return 0;
    1074                 :            : }
    1075                 :            : 
    1076                 :          0 : sal_Int32 DatabaseMetaData::getMaxTableNameLength(  ) throw (SQLException, RuntimeException)
    1077                 :            : {
    1078                 :          0 :     return getMaxNameLength();
    1079                 :            : }
    1080                 :            : 
    1081                 :          0 : sal_Int32 DatabaseMetaData::getMaxTablesInSelect(  ) throw (SQLException, RuntimeException)
    1082                 :            : {
    1083                 :          0 :     return 0;
    1084                 :            : }
    1085                 :            : 
    1086                 :          0 : sal_Int32 DatabaseMetaData::getMaxUserNameLength(  ) throw (SQLException, RuntimeException)
    1087                 :            : {
    1088                 :          0 :     return getMaxNameLength();
    1089                 :            : }
    1090                 :            : 
    1091                 :          0 : sal_Int32 DatabaseMetaData::getDefaultTransactionIsolation(  ) throw (SQLException, RuntimeException)
    1092                 :            : {
    1093                 :          0 :     return com::sun::star::sdbc::TransactionIsolation::READ_COMMITTED;
    1094                 :            : }
    1095                 :            : 
    1096                 :          0 : sal_Bool DatabaseMetaData::supportsTransactions(  ) throw (SQLException, RuntimeException)
    1097                 :            : {
    1098                 :          0 :     return sal_True;
    1099                 :            : }
    1100                 :            : 
    1101                 :          0 : sal_Bool DatabaseMetaData::supportsTransactionIsolationLevel( sal_Int32 level ) throw (SQLException, RuntimeException)
    1102                 :            : {
    1103                 :          0 :     if ( level == com::sun::star::sdbc::TransactionIsolation::READ_COMMITTED
    1104                 :            :          || level == com::sun::star::sdbc::TransactionIsolation::SERIALIZABLE
    1105                 :            :          || level == com::sun::star::sdbc::TransactionIsolation::READ_UNCOMMITTED
    1106                 :            :          || level == com::sun::star::sdbc::TransactionIsolation::REPEATABLE_READ)
    1107                 :          0 :         return sal_True;
    1108                 :            :     else
    1109                 :          0 :         return sal_False;
    1110                 :            : }
    1111                 :            : 
    1112                 :          0 : sal_Bool DatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions(  )
    1113                 :            :     throw (SQLException, RuntimeException)
    1114                 :            : {
    1115                 :          0 :     return sal_True;
    1116                 :            : }
    1117                 :            : 
    1118                 :          0 : sal_Bool DatabaseMetaData::supportsDataManipulationTransactionsOnly(  ) throw (SQLException, RuntimeException)
    1119                 :            : {
    1120                 :          0 :     return sal_False;
    1121                 :            : }
    1122                 :            : 
    1123                 :          0 : sal_Bool DatabaseMetaData::dataDefinitionCausesTransactionCommit(  ) throw (SQLException, RuntimeException)
    1124                 :            : {
    1125                 :          0 :     return sal_False;
    1126                 :            : }
    1127                 :            : 
    1128                 :          0 : sal_Bool DatabaseMetaData::dataDefinitionIgnoredInTransactions(  ) throw (SQLException, RuntimeException)
    1129                 :            : {
    1130                 :          0 :     return sal_False;
    1131                 :            : }
    1132                 :            : 
    1133                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getProcedures(
    1134                 :            :     const ::com::sun::star::uno::Any& catalog,
    1135                 :            :     const OUString& schemaPattern,
    1136                 :            :     const OUString& procedureNamePattern ) throw (SQLException, RuntimeException)
    1137                 :            : {
    1138                 :            :     (void) catalog; (void) schemaPattern; (void) procedureNamePattern;
    1139                 :            : //        1.  PROCEDURE_CAT string =&gt; procedure catalog (may be NULL )
    1140                 :            : //        2. PROCEDURE_SCHEM string =&gt; procedure schema (may be NULL )
    1141                 :            : //        3. PROCEDURE_NAME string =&gt; procedure name
    1142                 :            : //        4. reserved for future use
    1143                 :            : //        5. reserved for future use
    1144                 :            : //        6. reserved for future use
    1145                 :            : //        7. REMARKS string =&gt; explanatory comment on the procedure
    1146                 :            : //        8. PROCEDURE_TYPE short =&gt; kind of procedure:
    1147                 :            : //               * UNKNOWN - May return a result
    1148                 :            : //               * NO - Does not return a result
    1149                 :            : //               * RETURN - Returns a result
    1150                 :            : 
    1151                 :            : // LEM TODO: implement
    1152                 :            : // LEM TODO: at least fake the columns, even if no row.
    1153                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1154                 :          0 :     checkClosed();
    1155                 :            :     return new SequenceResultSet(
    1156                 :          0 :         m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc );
    1157                 :            : }
    1158                 :            : 
    1159                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getProcedureColumns(
    1160                 :            :     const ::com::sun::star::uno::Any& catalog,
    1161                 :            :     const OUString& schemaPattern,
    1162                 :            :     const OUString& procedureNamePattern,
    1163                 :            :     const OUString& columnNamePattern ) throw (SQLException, RuntimeException)
    1164                 :            : {
    1165                 :            :     (void) catalog; (void) schemaPattern; (void) procedureNamePattern; (void) columnNamePattern;
    1166                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1167                 :          0 :     checkClosed();
    1168                 :            : // LEM TODO: implement
    1169                 :            : // LEM TODO: at least fake the columns, even if no row.
    1170                 :            :     return new SequenceResultSet(
    1171                 :          0 :         m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc );
    1172                 :            : }
    1173                 :            : 
    1174                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTables(
    1175                 :            :     const ::com::sun::star::uno::Any& catalog,
    1176                 :            :     const OUString& schemaPattern,
    1177                 :            :     const OUString& tableNamePattern,
    1178                 :            :     const ::com::sun::star::uno::Sequence< OUString >& types )
    1179                 :            :     throw (SQLException, RuntimeException)
    1180                 :            : {
    1181                 :            :     (void) catalog; (void) types;
    1182                 :          0 :     Statics &statics = getStatics();
    1183                 :            : 
    1184                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1185                 :          0 :     checkClosed();
    1186                 :            : 
    1187                 :          0 :     if( isLog( m_pSettings, LogLevel::INFO ) )
    1188                 :            :     {
    1189                 :          0 :         rtl::OUStringBuffer buf( 128 );
    1190                 :          0 :         buf.appendAscii( "DatabaseMetaData::getTables got called with " );
    1191                 :          0 :         buf.append( schemaPattern );
    1192                 :          0 :         buf.appendAscii( "." );
    1193                 :          0 :         buf.append( tableNamePattern );
    1194                 :          0 :         log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() );
    1195                 :            :     }
    1196                 :            :     // ignore catalog, as a single pq connection does not support multiple catalogs
    1197                 :            : 
    1198                 :            :     // LEM TODO: this does not give the right column names, not the right number of columns, etc.
    1199                 :            :     // Take "inspiration" from JDBC driver
    1200                 :            :     // Ah, this is used to create a XResultSet manually... Try to do it directly in SQL
    1201                 :          0 :     Reference< XPreparedStatement > statement = m_origin->prepareStatement(
    1202                 :            :         ASCII_STR(
    1203                 :            :             "SELECT "
    1204                 :            :             "DISTINCT ON (pg_namespace.nspname, relname ) " // avoid duplicates (pg_settings !)
    1205                 :            :             "pg_namespace.nspname, relname, relkind, pg_description.description "
    1206                 :            :             "FROM pg_namespace, pg_class LEFT JOIN pg_description ON pg_class.oid = pg_description.objoid "
    1207                 :            :             "WHERE relnamespace = pg_namespace.oid "
    1208                 :            :             "AND ( relkind = 'r' OR relkind = 'v') "
    1209                 :            :             "AND pg_namespace.nspname LIKE ? "
    1210                 :            :             "AND relname LIKE ? "
    1211                 :            : //            "ORDER BY pg_namespace.nspname || relname"
    1212                 :          0 :             ) );
    1213                 :            : 
    1214                 :          0 :     Reference< XParameters > parameters( statement, UNO_QUERY_THROW );
    1215                 :          0 :     parameters->setString( 1 , schemaPattern );
    1216                 :          0 :     parameters->setString( 2 , tableNamePattern );
    1217                 :            : 
    1218                 :          0 :     Reference< XResultSet > rs = statement->executeQuery();
    1219                 :          0 :     Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    1220                 :          0 :     SequenceAnyVector vec;
    1221                 :            : 
    1222                 :          0 :     while( rs->next() )
    1223                 :            :     {
    1224                 :          0 :         Sequence< Any > row( 5 );
    1225                 :            : 
    1226                 :          0 :         row[0] <<= m_pSettings->catalog;
    1227                 :          0 :         row[1] <<= xRow->getString( 1 );
    1228                 :          0 :         row[2] <<= xRow->getString( 2 );
    1229                 :          0 :         OUString type = xRow->getString(3);
    1230                 :          0 :         if( 0 == type.compareToAscii( "r" ) )
    1231                 :            :         {
    1232                 :          0 :             if( 0 == xRow->getString(1).compareToAscii( "pg_catalog" ) )
    1233                 :            :             {
    1234                 :          0 :                 row[3] <<= statics.SYSTEM_TABLE;
    1235                 :            :             }
    1236                 :            :             else
    1237                 :            :             {
    1238                 :          0 :                 row[3] <<= statics.TABLE;
    1239                 :            :             }
    1240                 :            :         }
    1241                 :          0 :         else if( 0 == type.compareToAscii( "v" ) )
    1242                 :            :         {
    1243                 :          0 :             row[3] <<= statics.VIEW;
    1244                 :            :         }
    1245                 :            :         else
    1246                 :            :         {
    1247                 :          0 :             row[3] <<= statics.UNKNOWN;
    1248                 :            :         }
    1249                 :          0 :         row[4] <<= xRow->getString(4);
    1250                 :            : 
    1251                 :            :         // no description in postgresql AFAIK
    1252                 :          0 :         vec.push_back( row );
    1253                 :          0 :     }
    1254                 :          0 :     Reference< XCloseable > closeable( statement, UNO_QUERY );
    1255                 :          0 :     if( closeable.is() )
    1256                 :          0 :         closeable->close();
    1257                 :            : 
    1258                 :            :     return new SequenceResultSet(
    1259                 :          0 :         m_refMutex, *this, statics.tablesRowNames, sequence_of_vector(vec), m_pSettings->tc );
    1260                 :            : }
    1261                 :            : 
    1262                 :            : struct SortInternalSchemasLastAndPublicFirst
    1263                 :            : {
    1264                 :          0 :     bool operator () ( const Sequence< Any >  & a, const Sequence< Any >  & b )
    1265                 :            :     {
    1266                 :          0 :         OUString valueA;
    1267                 :          0 :         OUString valueB;
    1268                 :          0 :         a[0] >>= valueA;
    1269                 :          0 :         b[0] >>= valueB;
    1270                 :          0 :         bool ret = false;
    1271                 :          0 :         if( valueA.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "public" ) ) == 0 )
    1272                 :            :         {
    1273                 :          0 :             ret = true;
    1274                 :            :         }
    1275                 :          0 :         else if( valueB.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "public" ) ) == 0 )
    1276                 :            :         {
    1277                 :          0 :             ret = false;
    1278                 :            :         }
    1279                 :          0 :         else if( valueA.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) &&
    1280                 :          0 :             valueB.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) )
    1281                 :            :         {
    1282                 :          0 :             ret = valueA.compareTo( valueB ) < 0; // sorts equal !
    1283                 :            :         }
    1284                 :          0 :         else if( valueA.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ))
    1285                 :            :         {
    1286                 :          0 :             ret = false; // sorts last !
    1287                 :            :         }
    1288                 :          0 :         else if( valueB.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) )
    1289                 :            :         {
    1290                 :          0 :             ret = true; // sorts first !
    1291                 :            :         }
    1292                 :            :         else
    1293                 :            :         {
    1294                 :          0 :             ret = (valueA.compareTo( valueB ) < 0);
    1295                 :            :         }
    1296                 :          0 :         return ret;
    1297                 :            :     }
    1298                 :            : };
    1299                 :            : 
    1300                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getSchemas(  )
    1301                 :            :     throw (SQLException, RuntimeException)
    1302                 :            : {
    1303                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1304                 :          0 :     checkClosed();
    1305                 :            : 
    1306                 :          0 :     if( isLog( m_pSettings, LogLevel::INFO ) )
    1307                 :            :     {
    1308                 :          0 :         log( m_pSettings, LogLevel::INFO, "DatabaseMetaData::getSchemas() got called" );
    1309                 :            :     }
    1310                 :            :     // <b>TABLE_SCHEM</b> string =&amp;gt; schema name
    1311                 :          0 :     Reference< XStatement > statement = m_origin->createStatement();
    1312                 :          0 :     Reference< XResultSet > rs = statement->executeQuery(
    1313                 :          0 :         ASCII_STR("SELECT nspname from pg_namespace") );
    1314                 :            :     // LEM TODO: look at JDBC driver and consider doing the same
    1315                 :            :     //           in particular, excluding temporary schemas, but maybe better through pg_is_other_temp_schema(oid) OR  == pg_my_temp_schema()
    1316                 :            : 
    1317                 :          0 :     Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    1318                 :          0 :     SequenceAnyVector vec;
    1319                 :          0 :     while( rs->next() )
    1320                 :            :     {
    1321                 :          0 :         Sequence<Any> row(1);
    1322                 :          0 :         row[0] <<= xRow->getString(1);
    1323                 :          0 :         vec.push_back( row );
    1324                 :          0 :     }
    1325                 :            : 
    1326                 :            :     // sort public first, sort internal schemas last, sort rest in alphabetic order
    1327                 :          0 :     std::sort( vec.begin(), vec.end(), SortInternalSchemasLastAndPublicFirst() );
    1328                 :            : 
    1329                 :          0 :     Reference< XCloseable > closeable( statement, UNO_QUERY );
    1330                 :          0 :     if( closeable.is() )
    1331                 :          0 :         closeable->close();
    1332                 :            :     return new SequenceResultSet(
    1333                 :          0 :         m_refMutex, *this, getStatics().schemaNames, sequence_of_vector(vec), m_pSettings->tc );
    1334                 :            : }
    1335                 :            : 
    1336                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getCatalogs(  )
    1337                 :            :     throw (SQLException, RuntimeException)
    1338                 :            : {
    1339                 :            :     // LEM TODO: return the current catalog like JDBC driver?
    1340                 :            :     //           at least fake the columns, even if no content
    1341                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1342                 :          0 :     checkClosed();
    1343                 :            :     return new SequenceResultSet(
    1344                 :          0 :         m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc );
    1345                 :            : }
    1346                 :            : 
    1347                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTableTypes(  )
    1348                 :            :     throw (SQLException, RuntimeException)
    1349                 :            : {
    1350                 :            :     // LEM TODO: this can be made dynamic, see JDBC driver
    1351                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1352                 :          0 :     checkClosed();
    1353                 :            :     return new SequenceResultSet(
    1354                 :          0 :         m_refMutex, *this, getStatics().tableTypeNames, getStatics().tableTypeData,
    1355                 :          0 :         m_pSettings->tc );
    1356                 :            : }
    1357                 :            : 
    1358                 :            : 
    1359                 :            : /** returns the constant from sdbc.DataType
    1360                 :            :  */
    1361                 :          0 : sal_Int32 typeNameToDataType( const OUString &typeName, const OUString &typtype )
    1362                 :            : {
    1363                 :            : //     sal_Int32 ret = com::sun::star::sdbc::DataType::DISTINCT;
    1364                 :            :     // map all unknown types to memo (longvarchar). This allows to show them in
    1365                 :            :     // string representation. Additionally, the edit-table-type-selection-box
    1366                 :            :     // is not so unuseable anymore.
    1367                 :          0 :     sal_Int32 ret = com::sun::star::sdbc::DataType::LONGVARCHAR;
    1368                 :          0 :     if( 0 == typtype.compareToAscii( "b" ) )
    1369                 :            :     {
    1370                 :            :         // as long as the OOo framework does not support arrays,
    1371                 :            :         // the user is better of with interpreting arrays as strings !
    1372                 :            : //         if( typeName.getLength() && '_' == typeName[0] )
    1373                 :            : //         {
    1374                 :            : //             its just a naming convention, but as long as we don't have anything better,
    1375                 :            : //             we take it as granted
    1376                 :            : //             ret = com::sun::star::sdbc::DataType::ARRAY;
    1377                 :            : //         }
    1378                 :            :         // base type
    1379                 :          0 :         Statics &statics = getStatics();
    1380                 :          0 :         BaseTypeMap::iterator ii = statics.baseTypeMap.find( typeName );
    1381                 :          0 :         if( ii != statics.baseTypeMap.end() )
    1382                 :            :         {
    1383                 :          0 :             ret = ii->second;
    1384                 :            :         }
    1385                 :            :     }
    1386                 :          0 :     else if( 0 == typtype.compareToAscii( "c" ) )
    1387                 :            :     {
    1388                 :          0 :         ret = com::sun::star::sdbc::DataType::STRUCT;
    1389                 :            :     }
    1390                 :          0 :     else if( 0 == typtype.compareToAscii( "d" ) )
    1391                 :            :     {
    1392                 :          0 :         ret = com::sun::star::sdbc::DataType::LONGVARCHAR;
    1393                 :            :     }
    1394                 :          0 :     return ret;
    1395                 :            : }
    1396                 :            : 
    1397                 :            : namespace {
    1398                 :          0 : inline bool isSystemColumn( sal_Int16 attnum )
    1399                 :            : {
    1400                 :          0 :     return attnum <= 0;
    1401                 :            : }
    1402                 :            : }
    1403                 :            : 
    1404                 :            : // is not exported by the postgres header
    1405                 :            : const static int PQ_VARHDRSZ = sizeof( sal_Int32 );
    1406                 :            : 
    1407                 :            : // Oh, quelle horreur
    1408                 :            : // LEM TODO: Need to severely rewrite that!
    1409                 :            : // should probably just "do the same" as ODBC or JDBC drivers...
    1410                 :          0 : static void extractPrecisionAndScale(
    1411                 :            :     sal_Int32 dataType, sal_Int32 atttypmod, sal_Int32 *precision, sal_Int32 *scale )
    1412                 :            : {
    1413                 :          0 :     if( atttypmod < PQ_VARHDRSZ )
    1414                 :            :     {
    1415                 :          0 :         *precision = 0;
    1416                 :          0 :         *scale = 0;
    1417                 :            :     }
    1418                 :            :     else
    1419                 :            :     {
    1420                 :          0 :         switch( dataType )
    1421                 :            :         {
    1422                 :            :         case com::sun::star::sdbc::DataType::NUMERIC:
    1423                 :            :         case com::sun::star::sdbc::DataType::DECIMAL:
    1424                 :            :         {
    1425                 :          0 :             *precision = ( ( atttypmod - PQ_VARHDRSZ ) >> 16 ) & 0xffff;
    1426                 :          0 :             *scale = (atttypmod - PQ_VARHDRSZ ) & 0xffff;
    1427                 :          0 :             break;
    1428                 :            :         }
    1429                 :            :         default:
    1430                 :          0 :             *precision = atttypmod - PQ_VARHDRSZ;
    1431                 :          0 :             *scale = 0;
    1432                 :            :         }
    1433                 :            :     }
    1434                 :          0 : }
    1435                 :            : 
    1436                 :          0 : struct DatabaseTypeDescription
    1437                 :            : {
    1438                 :          0 :     DatabaseTypeDescription()
    1439                 :          0 :     {}
    1440                 :          0 :     DatabaseTypeDescription( const OUString &name, const OUString & type ) :
    1441                 :            :         typeName( name ),
    1442                 :          0 :         typeType( type )
    1443                 :          0 :     {}
    1444                 :          0 :     DatabaseTypeDescription( const DatabaseTypeDescription &source ) :
    1445                 :            :         typeName( source.typeName ),
    1446                 :          0 :         typeType( source.typeType )
    1447                 :          0 :     {}
    1448                 :          0 :     DatabaseTypeDescription & operator = ( const DatabaseTypeDescription & source )
    1449                 :            :     {
    1450                 :          0 :         typeName = source.typeName;
    1451                 :          0 :         typeType = source.typeType;
    1452                 :          0 :         return *this;
    1453                 :            :     }
    1454                 :            :     OUString typeName;
    1455                 :            :     OUString typeType;
    1456                 :            : };
    1457                 :            : 
    1458                 :            : typedef ::boost::unordered_map
    1459                 :            : <
    1460                 :            :     sal_Int32,
    1461                 :            :     DatabaseTypeDescription,
    1462                 :            :     ::boost::hash< sal_Int32 >,
    1463                 :            :     ::std::equal_to< sal_Int32 >,
    1464                 :            :     Allocator< ::std::pair< sal_Int32, DatabaseTypeDescription > >
    1465                 :            : > Oid2DatabaseTypeDescriptionMap;
    1466                 :            : 
    1467                 :          0 : static void columnMetaData2DatabaseTypeDescription(
    1468                 :            :     Oid2DatabaseTypeDescriptionMap &oidMap,
    1469                 :            :     const Reference< XResultSet > &rs,
    1470                 :            :     const Reference< XStatement > &stmt )
    1471                 :            : {
    1472                 :          0 :     Reference< XRow > row( rs, UNO_QUERY_THROW );
    1473                 :          0 :     int domains = 0;
    1474                 :          0 :     rtl::OUStringBuffer queryBuf(128);
    1475                 :          0 :     queryBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT oid,typtype,typname FROM pg_TYPE WHERE " ) );
    1476                 :          0 :     while( rs->next() )
    1477                 :            :     {
    1478                 :          0 :         if( row->getString( 9 ) == "d" && oidMap.find( row->getInt( 12 ) ) == oidMap.end() )
    1479                 :            :         {
    1480                 :          0 :             oidMap[row->getInt(12)] = DatabaseTypeDescription();
    1481                 :          0 :             if( domains )
    1482                 :          0 :                 queryBuf.appendAscii( " OR " );
    1483                 :          0 :             queryBuf.appendAscii( "oid = " );
    1484                 :          0 :             queryBuf.append( row->getInt(12 ), 10 );
    1485                 :          0 :             domains ++;
    1486                 :            :         }
    1487                 :            :     }
    1488                 :          0 :     rs->beforeFirst();
    1489                 :            : 
    1490                 :          0 :     if( domains )
    1491                 :            :     {
    1492                 :          0 :         Reference< XResultSet > rsDomain = stmt->executeQuery( queryBuf.makeStringAndClear() );
    1493                 :          0 :         row = Reference< XRow >( rsDomain, UNO_QUERY_THROW );
    1494                 :          0 :         while( rsDomain->next() )
    1495                 :            :         {
    1496                 :          0 :             oidMap[row->getInt(1)] = DatabaseTypeDescription(row->getString(3), row->getString(2) );
    1497                 :            :         }
    1498                 :          0 :         disposeNoThrow( stmt );
    1499                 :          0 :     }
    1500                 :            : 
    1501                 :          0 : }
    1502                 :            : 
    1503                 :            : 
    1504                 :            : 
    1505                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getColumns(
    1506                 :            :     const ::com::sun::star::uno::Any& catalog,
    1507                 :            :     const OUString& schemaPattern,
    1508                 :            :     const OUString& tableNamePattern,
    1509                 :            :     const OUString& columnNamePattern ) throw (SQLException, RuntimeException)
    1510                 :            : {
    1511                 :            :     (void) catalog;
    1512                 :            :     // LEM TODO: review in comparison with JDBC driver
    1513                 :          0 :     Statics &statics = getStatics();
    1514                 :            : 
    1515                 :            :     // continue !
    1516                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1517                 :          0 :     checkClosed();
    1518                 :            : 
    1519                 :          0 :     if( isLog( m_pSettings, LogLevel::INFO ) )
    1520                 :            :     {
    1521                 :          0 :         rtl::OUStringBuffer buf( 128 );
    1522                 :          0 :         buf.appendAscii( "DatabaseMetaData::getColumns got called with " );
    1523                 :          0 :         buf.append( schemaPattern );
    1524                 :          0 :         buf.appendAscii( "." );
    1525                 :          0 :         buf.append( tableNamePattern );
    1526                 :          0 :         buf.appendAscii( "." );
    1527                 :          0 :         buf.append( columnNamePattern );
    1528                 :          0 :         log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() );
    1529                 :            :     }
    1530                 :            : 
    1531                 :            :     // ignore catalog, as a single pq connection
    1532                 :            :     // does not support multiple catalogs anyway
    1533                 :            :     // We don't use information_schema.columns because it contains
    1534                 :            :     // only the columns the current user has any privilege over.
    1535                 :            : 
    1536                 :            :     //  1. TABLE_CAT string => table catalog (may be NULL)
    1537                 :            :     //               => not supported
    1538                 :            :     //  2. TABLE_SCHEM string => table schema (may be NULL)
    1539                 :            :     //               => pg_namespace.nspname
    1540                 :            :     //  3. TABLE_NAME string => table name
    1541                 :            :     //               => pg_class.relname
    1542                 :            :     //  4. COLUMN_NAME string => column name
    1543                 :            :     //               => pg_attribure.attname
    1544                 :            :     //  5. DATA_TYPE short => SQL type from java.sql.Types
    1545                 :            :     //               => pg_type.typname => sdbc.DataType
    1546                 :            :     //  6. TYPE_NAME string => Data source dependent type name, for a UDT the
    1547                 :            :     //                         type name is fully qualified
    1548                 :            :     //               => pg_type.typname
    1549                 :            :     //  7. COLUMN_SIZE long => column size. For char or date types this is
    1550                 :            :     //                         the maximum number of characters, for numeric
    1551                 :            :     //                         or decimal types this is precision.
    1552                 :            :     //               => pg_attribute.atttypmod
    1553                 :            :     //  8. BUFFER_LENGTH is not used.
    1554                 :            :     //               => not used
    1555                 :            :     //  9. DECIMAL_DIGITS long => the number of fractional digits
    1556                 :            :     //               => don't know ! TODO !
    1557                 :            :     //  10. NUM_PREC_RADIX long => Radix (typically either 10 or 2)
    1558                 :            :     //               => TODO ??
    1559                 :            :     //  11. NULLABLE long => is NULL allowed?
    1560                 :            :     //                      NO_NULLS - might not allow NULL values
    1561                 :            :     //                      NULABLE - definitely allows NULL values
    1562                 :            :     //                      NULLABLE_UNKNOWN - nullability unknown
    1563                 :            :     //               => pg_attribute.attnotnull
    1564                 :            :     //  12. REMARKS string => comment describing column (may be NULL )
    1565                 :            :     //               => pg_description.description
    1566                 :            :     //  13. COLUMN_DEF string => default value (may be NULL)
    1567                 :            :     //               => pg_type.typdefault
    1568                 :            :     //  14. SQL_DATA_TYPE long => unused
    1569                 :            :     //               => empty
    1570                 :            :     //  15. SQL_DATETIME_SUB long => unused
    1571                 :            :     //               => empty
    1572                 :            :     //  16. CHAR_OCTET_LENGTH long => for char types the maximum number of
    1573                 :            :     //                                bytes in the column
    1574                 :            :     //               => pg_type.typlen
    1575                 :            :     //  17. ORDINAL_POSITION int => index of column in table (starting at 1)
    1576                 :            :     //                              pg_attribute.attnum
    1577                 :            :     //  18. IS_NULLABLE string => "NO" means column definitely does not allow
    1578                 :            :     //                            NULL values; "YES" means the column might
    1579                 :            :     //                            allow NULL values. An empty string means
    1580                 :            :     //                            nobody knows.
    1581                 :            :     //               => pg_attribute.attnotnull
    1582                 :            : 
    1583                 :          0 :     Reference< XPreparedStatement > statement = m_origin->prepareStatement(
    1584                 :            :         ASCII_STR(
    1585                 :            : 
    1586                 :            :             "SELECT pg_namespace.nspname, "  // 1
    1587                 :            :             "pg_class.relname, "             // 2
    1588                 :            :             "pg_attribute.attname, "         // 3
    1589                 :            :             "pg_type.typname, "              // 4
    1590                 :            :             "pg_attribute.atttypmod, "       // 5
    1591                 :            :             "pg_attribute.attnotnull, "      // 6
    1592                 :            :             "pg_type.typdefault, "           // 7
    1593                 :            :             "pg_type.typtype, "              // 8
    1594                 :            :             "pg_attrdef.adsrc, "             // 9
    1595                 :            :             "pg_description.description, "   // 10
    1596                 :            :             "pg_type.typbasetype, "          // 11
    1597                 :            :             "pg_attribute.attnum "           // 12
    1598                 :            :             "FROM pg_class, "
    1599                 :            :                  "pg_attribute LEFT JOIN pg_attrdef ON pg_attribute.attrelid = pg_attrdef.adrelid AND pg_attribute.attnum = pg_attrdef.adnum "
    1600                 :            :                               "LEFT JOIN pg_description ON pg_attribute.attrelid = pg_description.objoid AND pg_attribute.attnum=pg_description.objsubid,"
    1601                 :            :                  " pg_type, pg_namespace "
    1602                 :            :             "WHERE pg_attribute.attrelid = pg_class.oid "
    1603                 :            :                    "AND pg_attribute.atttypid = pg_type.oid "
    1604                 :            :                    "AND pg_class.relnamespace = pg_namespace.oid "
    1605                 :            :                    "AND NOT pg_attribute.attisdropped "
    1606                 :            :                    "AND pg_namespace.nspname LIKE ? "
    1607                 :            :                    "AND pg_class.relname LIKE ? "
    1608                 :            :                    "AND pg_attribute.attname LIKE ? "
    1609                 :            :             "ORDER BY pg_namespace.nspname, pg_class.relname, pg_attribute.attnum"
    1610                 :          0 :             ) );
    1611                 :            : 
    1612                 :          0 :     Reference< XParameters > parameters( statement, UNO_QUERY_THROW );
    1613                 :          0 :     parameters->setString( 1 , schemaPattern );
    1614                 :          0 :     parameters->setString( 2 , tableNamePattern );
    1615                 :          0 :     parameters->setString( 3 , columnNamePattern );
    1616                 :            : 
    1617                 :          0 :     Reference< XResultSet > rs = statement->executeQuery();
    1618                 :          0 :     Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    1619                 :          0 :     SequenceAnyVector vec;
    1620                 :            : 
    1621                 :          0 :     Oid2DatabaseTypeDescriptionMap domainMap;
    1622                 :          0 :     Reference< XStatement > domainTypeStmt = m_origin->createStatement();
    1623                 :          0 :     columnMetaData2DatabaseTypeDescription( domainMap, rs, domainTypeStmt );
    1624                 :            : 
    1625                 :          0 :     sal_uInt32 colNum(0);
    1626                 :          0 :     OUString sSchema( ASCII_STR("#invalid#") );
    1627                 :          0 :     OUString sTable(  ASCII_STR("#invalid#") );
    1628                 :            : 
    1629                 :          0 :     while( rs->next() )
    1630                 :            :     {
    1631                 :          0 :         if( m_pSettings->showSystemColumns || ! isSystemColumn( xRow->getShort( 12 ) ) )
    1632                 :            :         {
    1633                 :          0 :             OUString sNewSchema( xRow->getString(1) );
    1634                 :          0 :             OUString sNewTable(  xRow->getString(2) );
    1635                 :          0 :             if ( sNewSchema != sSchema || sNewTable != sTable )
    1636                 :            :             {
    1637                 :          0 :                 colNum = 1;
    1638                 :          0 :                 sSchema = sNewSchema;
    1639                 :          0 :                 sTable = sNewTable;
    1640                 :            :             }
    1641                 :            :             else
    1642                 :          0 :                 ++colNum;
    1643                 :            :             sal_Int32 precision, scale, type;
    1644                 :          0 :             Sequence< Any > row( 18 );
    1645                 :          0 :             row[0] <<= m_pSettings->catalog;
    1646                 :          0 :             row[1] <<= sNewSchema;
    1647                 :          0 :             row[2] <<= sNewTable;
    1648                 :          0 :             row[3] <<= xRow->getString(3);
    1649                 :          0 :             if( xRow->getString(8) == "d" )
    1650                 :            :             {
    1651                 :          0 :                 DatabaseTypeDescription desc( domainMap[xRow->getInt(11)] );
    1652                 :          0 :                 type = typeNameToDataType( desc.typeName, desc.typeType );
    1653                 :            :             }
    1654                 :            :             else
    1655                 :            :             {
    1656                 :          0 :                 type = typeNameToDataType( xRow->getString(4), xRow->getString(8) );
    1657                 :            :             }
    1658                 :          0 :             extractPrecisionAndScale( type, xRow->getInt(5) , &precision, &scale );
    1659                 :          0 :             row[4] <<= type;
    1660                 :          0 :             row[5] <<= xRow->getString(4);
    1661                 :          0 :             row[6] <<= precision;
    1662                 :            :             // row[7] BUFFER_LENGTH not used
    1663                 :          0 :             row[8] <<= scale;
    1664                 :            :             // row[9] RADIX TODO
    1665                 :          0 :             if( xRow->getBoolean( 6 ) && ! isSystemColumn(xRow->getInt( 12 )) )
    1666                 :            :             {
    1667                 :          0 :                 row[10] <<= OUString::valueOf(com::sun::star::sdbc::ColumnValue::NO_NULLS);
    1668                 :          0 :                 row[17] <<= statics.NO;
    1669                 :            :             }
    1670                 :            :             else
    1671                 :            :             {
    1672                 :          0 :                 row[10] <<= OUString::valueOf(com::sun::star::sdbc::ColumnValue::NULLABLE);
    1673                 :          0 :                 row[17] <<= statics.YES;
    1674                 :            :             }
    1675                 :            : 
    1676                 :          0 :             row[11] <<= xRow->getString( 10 ); // comment
    1677                 :          0 :             row[12] <<= xRow->getString( 9 ); // COLUMN_DEF = pg_type.typdefault
    1678                 :            :             // row[13] SQL_DATA_TYPE    not used
    1679                 :            :             // row[14] SQL_DATETIME_SUB not used
    1680                 :          0 :             row[15] <<= precision;
    1681                 :          0 :             row[16] <<= colNum ;
    1682                 :            : 
    1683                 :          0 :             vec.push_back( row );
    1684                 :            :         }
    1685                 :            :     }
    1686                 :          0 :     Reference< XCloseable > closeable( statement, UNO_QUERY );
    1687                 :          0 :     if( closeable.is() )
    1688                 :          0 :         closeable->close();
    1689                 :            : 
    1690                 :            :     return new SequenceResultSet(
    1691                 :          0 :         m_refMutex, *this, statics.columnRowNames, sequence_of_vector(vec), m_pSettings->tc );
    1692                 :            : }
    1693                 :            : 
    1694                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getColumnPrivileges(
    1695                 :            :     const ::com::sun::star::uno::Any& catalog,
    1696                 :            :     const OUString& schema,
    1697                 :            :     const OUString& table,
    1698                 :            :     const OUString& columnNamePattern ) throw (SQLException, RuntimeException)
    1699                 :            : {
    1700                 :            :     (void) catalog;
    1701                 :            : 
    1702                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1703                 :          0 :     checkClosed();
    1704                 :            : 
    1705                 :          0 :     if( isLog( m_pSettings, LogLevel::INFO ) )
    1706                 :            :     {
    1707                 :          0 :         rtl::OUStringBuffer buf( 128 );
    1708                 :          0 :         buf.appendAscii( "DatabaseMetaData::getColumnPrivileges got called with " );
    1709                 :          0 :         buf.append( schema );
    1710                 :          0 :         buf.appendAscii( "." );
    1711                 :          0 :         buf.append( table );
    1712                 :          0 :         buf.appendAscii( "." );
    1713                 :          0 :         buf.append( columnNamePattern );
    1714                 :          0 :         log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() );
    1715                 :            :     }
    1716                 :            : 
    1717                 :          0 :     Reference< XParameters > parameters( m_getColumnPrivs_stmt, UNO_QUERY_THROW );
    1718                 :          0 :     parameters->setString( 1 , schema );
    1719                 :          0 :     parameters->setString( 2 , table );
    1720                 :          0 :     parameters->setString( 3 , columnNamePattern );
    1721                 :            : 
    1722                 :          0 :     Reference< XResultSet > rs = m_getColumnPrivs_stmt->executeQuery();
    1723                 :            : 
    1724                 :          0 :     return rs;
    1725                 :            : }
    1726                 :            : 
    1727                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTablePrivileges(
    1728                 :            :     const ::com::sun::star::uno::Any& catalog,
    1729                 :            :     const OUString& schemaPattern,
    1730                 :            :     const OUString& tableNamePattern ) throw (SQLException, RuntimeException)
    1731                 :            : {
    1732                 :            :     (void) catalog;
    1733                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1734                 :          0 :     checkClosed();
    1735                 :            : 
    1736                 :          0 :     if( isLog( m_pSettings, LogLevel::INFO ) )
    1737                 :            :     {
    1738                 :          0 :         rtl::OUStringBuffer buf( 128 );
    1739                 :          0 :         buf.appendAscii( "DatabaseMetaData::getTablePrivileges got called with " );
    1740                 :          0 :         buf.append( schemaPattern );
    1741                 :          0 :         buf.appendAscii( "." );
    1742                 :          0 :         buf.append( tableNamePattern );
    1743                 :          0 :         log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() );
    1744                 :            :     }
    1745                 :            : 
    1746                 :          0 :     Reference< XParameters > parameters( m_getTablePrivs_stmt, UNO_QUERY_THROW );
    1747                 :          0 :     parameters->setString( 1 , schemaPattern );
    1748                 :          0 :     parameters->setString( 2 , tableNamePattern );
    1749                 :            : 
    1750                 :          0 :     Reference< XResultSet > rs = m_getTablePrivs_stmt->executeQuery();
    1751                 :            : 
    1752                 :          0 :     return rs;
    1753                 :            : }
    1754                 :            : 
    1755                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getBestRowIdentifier(
    1756                 :            :     const ::com::sun::star::uno::Any& catalog,
    1757                 :            :     const OUString& schema,
    1758                 :            :     const OUString& table,
    1759                 :            :     sal_Int32 scope,
    1760                 :            :     sal_Bool nullable ) throw (SQLException, RuntimeException)
    1761                 :            : {
    1762                 :            :     (void) catalog; (void) schema; (void) table; (void) scope; (void) nullable;
    1763                 :            :     //LEM TODO: implement! See JDBC driver
    1764                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1765                 :          0 :     checkClosed();
    1766                 :            :     return new SequenceResultSet(
    1767                 :          0 :         m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc );
    1768                 :            : }
    1769                 :            : 
    1770                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getVersionColumns(
    1771                 :            :     const ::com::sun::star::uno::Any& catalog,
    1772                 :            :     const OUString& schema,
    1773                 :            :     const OUString& table ) throw (SQLException, RuntimeException)
    1774                 :            : {
    1775                 :            :     (void) catalog; (void) schema; (void) table;
    1776                 :            :     //LEM TODO: implement! See JDBC driver
    1777                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1778                 :          0 :     checkClosed();
    1779                 :            :     return new SequenceResultSet(
    1780                 :          0 :         m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc );
    1781                 :            : }
    1782                 :            : 
    1783                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getPrimaryKeys(
    1784                 :            :     const ::com::sun::star::uno::Any& catalog,
    1785                 :            :     const OUString& schema,
    1786                 :            :     const OUString& table ) throw (SQLException, RuntimeException)
    1787                 :            : {
    1788                 :            :     (void) catalog;
    1789                 :            :     //LEM TODO: review
    1790                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    1791                 :          0 :     checkClosed();
    1792                 :            : 
    1793                 :            : //        1.  TABLE_CAT string =&gt; table catalog (may be NULL )
    1794                 :            : //        2. TABLE_SCHEM string =&gt; table schema (may be NULL )
    1795                 :            : //        3. TABLE_NAME string =&gt; table name
    1796                 :            : //        4. COLUMN_NAME string =&gt; column name
    1797                 :            : //        5. KEY_SEQ short =&gt; sequence number within primary key
    1798                 :            : //        6. PK_NAME string =&gt; primary key name (may be NULL )
    1799                 :            : 
    1800                 :          0 :     if( isLog( m_pSettings, LogLevel::INFO ) )
    1801                 :            :     {
    1802                 :          0 :         rtl::OUStringBuffer buf( 128 );
    1803                 :          0 :         buf.appendAscii( "DatabaseMetaData::getPrimaryKeys got called with " );
    1804                 :          0 :         buf.append( schema );
    1805                 :          0 :         buf.appendAscii( "." );
    1806                 :          0 :         buf.append( table );
    1807                 :          0 :         log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() );
    1808                 :            :     }
    1809                 :            : 
    1810                 :          0 :     Reference< XPreparedStatement > statement = m_origin->prepareStatement(
    1811                 :            :         ASCII_STR(
    1812                 :            :             "SELECT nmsp.nspname, "
    1813                 :            :                     "cl.relname, "
    1814                 :            :                     "con.conkey, "
    1815                 :            :                     "con.conname, "
    1816                 :            :                     "con.conrelid "
    1817                 :            :             "FROM pg_constraint as con,pg_class as cl, pg_namespace as nmsp "
    1818                 :            :             "WHERE con.connamespace = nmsp.oid AND con.conrelid = cl.oid AND con.contype = 'p' "
    1819                 :          0 :                 "AND nmsp.nspname LIKE ? AND cl.relname LIKE ?" ) );
    1820                 :            : 
    1821                 :          0 :     Reference< XParameters > parameters( statement, UNO_QUERY_THROW );
    1822                 :          0 :     parameters->setString( 1 , schema );
    1823                 :          0 :     parameters->setString( 2 , table );
    1824                 :            : 
    1825                 :          0 :     Reference< XResultSet > rs = statement->executeQuery();
    1826                 :          0 :     Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    1827                 :          0 :     SequenceAnyVector vec;
    1828                 :            : 
    1829                 :          0 :     while( rs->next() )
    1830                 :            :     {
    1831                 :          0 :         Sequence< Any > row( 6 );
    1832                 :          0 :         row[0] <<= m_pSettings->catalog;
    1833                 :          0 :         row[1] <<= xRow->getString(1);  //
    1834                 :          0 :         row[2] <<= xRow->getString(2);
    1835                 :          0 :         OUString array = xRow->getString(3);
    1836                 :          0 :         row[4] <<= xRow->getString(5); // the relid
    1837                 :          0 :         row[5] <<= xRow->getString(4);
    1838                 :            : 
    1839                 :          0 :         int i = 0;
    1840                 :            :         // now retrieve the columns information
    1841                 :            :         // unfortunately, postgresql does not allow array of variable size in
    1842                 :            :         // WHERE clauses (in the default installation), so we have to choose
    1843                 :            :         // this expensive and somewhat ugly way
    1844                 :            :         // annotation: postgresql shouldn't have choosen an array here, instead they
    1845                 :            :         //             should have multiple rows per table
    1846                 :            :         // LEM: to transform an array into several rows, see unnest;
    1847                 :            :         //      it is as simple as "SELECT foo, bar, unnest(qux) FROM ..."
    1848                 :            :         //      where qux is the column that contains an array.
    1849                 :          0 :         while( array[i] && '}' != array[i] )
    1850                 :            :         {
    1851                 :          0 :             i++;
    1852                 :          0 :             int start = i;
    1853                 :          0 :             while( array[i] && array[i] != '}' && array[i] != ',' ) i++;
    1854                 :          0 :             row[3] <<= OUString( &array.getStr()[start], i - start );
    1855                 :          0 :             vec.push_back( row );
    1856                 :            :         }
    1857                 :          0 :     }
    1858                 :            : 
    1859                 :            :     {
    1860                 :          0 :         Reference< XCloseable > closeable( statement, UNO_QUERY );
    1861                 :          0 :         if( closeable.is() )
    1862                 :          0 :             closeable->close();
    1863                 :            :     }
    1864                 :            : 
    1865                 :            : 
    1866                 :          0 :     SequenceAnyVector::iterator ii = vec.begin();
    1867                 :          0 :     OUString lastTableOid;
    1868                 :          0 :     sal_Int32 index = 0;
    1869                 :          0 :     Sequence< Sequence< Any > > ret( vec.size() );
    1870                 :          0 :     int elements = 0;
    1871                 :          0 :     for( ; ii != vec.end() ; ++ ii )
    1872                 :            :     {
    1873                 :            : 
    1874                 :          0 :         Sequence< Any > row = *ii;
    1875                 :          0 :         OUString tableOid;
    1876                 :          0 :         OUString attnum;
    1877                 :            : 
    1878                 :          0 :         row[4] >>= tableOid;
    1879                 :          0 :         row[3] >>= attnum;
    1880                 :          0 :         statement = m_origin->prepareStatement(
    1881                 :            :             ASCII_STR(
    1882                 :            :                 "SELECT att.attname FROM "
    1883                 :            :                 "pg_attribute AS att, pg_class AS cl WHERE "
    1884                 :          0 :                 "att.attrelid = ? AND att.attnum = ?" ));
    1885                 :            : 
    1886                 :          0 :         parameters = Reference< XParameters >( statement, UNO_QUERY_THROW );
    1887                 :          0 :         parameters->setString( 1 , tableOid );
    1888                 :          0 :         parameters->setString( 2 , attnum );
    1889                 :            : 
    1890                 :          0 :         rs = statement->executeQuery();
    1891                 :          0 :         xRow = Reference< XRow >( rs, UNO_QUERY_THROW );
    1892                 :          0 :         if( rs->next() )
    1893                 :            :         {
    1894                 :            :             // column name
    1895                 :          0 :             row[3] <<= xRow->getString( 1 );
    1896                 :          0 :             if( tableOid != lastTableOid )
    1897                 :          0 :                 index = 1;
    1898                 :          0 :             lastTableOid = tableOid;
    1899                 :          0 :             row[4] <<= OUString::valueOf( index );
    1900                 :          0 :             index ++;
    1901                 :            :         }
    1902                 :            :         {
    1903                 :          0 :             Reference< XCloseable > closeable( statement, UNO_QUERY );
    1904                 :          0 :             if( closeable.is() )
    1905                 :          0 :                 closeable->close();
    1906                 :            :         }
    1907                 :          0 :         ret[elements] = row;
    1908                 :          0 :         elements ++;
    1909                 :          0 :     }
    1910                 :            :     return new SequenceResultSet(
    1911                 :          0 :         m_refMutex, *this, getStatics().primaryKeyNames, ret , m_pSettings->tc );
    1912                 :            : }
    1913                 :            : 
    1914                 :            : // Copied / adapted / simplified from JDBC driver
    1915                 :            : #define SQL_CASE_KEYRULE "  WHEN 'c' THEN " STRINGIFY(KEYRULE_CASCADE) \
    1916                 :            :                          "  WHEN 'n' THEN " STRINGIFY(KEYRULE_SET_NULL) \
    1917                 :            :                          "  WHEN 'd' THEN " STRINGIFY(KEYRULE_SET_DEFAULT) \
    1918                 :            :                          "  WHEN 'r' THEN " STRINGIFY(KEYRULE_RESTRICT) \
    1919                 :            :                          "  WHEN 'a' THEN " STRINGIFY(KEYRULE_NO_ACTION) \
    1920                 :            :                          "  ELSE NULL "
    1921                 :            : 
    1922                 :            : #define SQL_GET_REFERENCES \
    1923                 :            :     "WITH con AS (SELECT oid, conname, contype, condeferrable, condeferred, conrelid, confrelid,  confupdtype, confdeltype, generate_subscripts(conkey,1) AS conkeyseq, unnest(conkey) AS conkey , unnest(confkey) AS confkey FROM pg_catalog.pg_constraint) " \
    1924                 :            :     "SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEM, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, " \
    1925                 :            :     " NULL::text AS FKTABLE_CAT, fkn.nspname AS FKTABLE_SCHEM, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, " \
    1926                 :            :     " con.conkeyseq AS KEY_SEQ, " \
    1927                 :            :     " CASE con.confupdtype " \
    1928                 :            :     SQL_CASE_KEYRULE \
    1929                 :            :     " END AS UPDATE_RULE, " \
    1930                 :            :     " CASE con.confdeltype " \
    1931                 :            :     SQL_CASE_KEYRULE \
    1932                 :            :     " END AS DELETE_RULE, " \
    1933                 :            :     " con.conname AS FK_NAME, pkic.relname AS PK_NAME, " \
    1934                 :            :     " CASE " \
    1935                 :            :     "  WHEN con.condeferrable AND con.condeferred THEN " STRINGIFY(DEFERRABILITY_INITIALLY_DEFERRED) \
    1936                 :            :     "  WHEN con.condeferrable THEN " STRINGIFY(DEFERRABILITY_INITIALLY_IMMEDIATE) \
    1937                 :            :     "  ELSE " STRINGIFY(DEFERRABILITY_NONE) \
    1938                 :            :     " END AS DEFERRABILITY " \
    1939                 :            :     "FROM " \
    1940                 :            :     " pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, " \
    1941                 :            :     " pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka, " \
    1942                 :            :     " con, pg_catalog.pg_depend dep, pg_catalog.pg_class pkic " \
    1943                 :            :     "WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey AND con.confrelid = pkc.oid " \
    1944                 :            :     " AND  fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey  AND con.conrelid  = fkc.oid " \
    1945                 :            :     " AND con.contype = 'f' AND con.oid = dep.objid AND pkic.oid = dep.refobjid AND pkic.relkind = 'i' AND dep.classid = 'pg_constraint'::regclass::oid AND dep.refclassid = 'pg_class'::regclass::oid "
    1946                 :            : 
    1947                 :            : #define SQL_GET_REFERENCES_PSCHEMA " AND pkn.nspname = ? "
    1948                 :            : #define SQL_GET_REFERENCES_PTABLE  " AND pkc.relname = ? "
    1949                 :            : #define SQL_GET_REFERENCES_FSCHEMA " AND fkn.nspname = ? "
    1950                 :            : #define SQL_GET_REFERENCES_FTABLE  " AND fkc.relname = ? "
    1951                 :            : #define SQL_GET_REFERENCES_ORDER_SOME_PTABLE "ORDER BY fkn.nspname, fkc.relname, conkeyseq"
    1952                 :            : #define SQL_GET_REFERENCES_ORDER_NO_PTABLE   "ORDER BY pkn.nspname, pkc.relname, conkeyseq"
    1953                 :            : 
    1954                 :            : #define SQL_GET_REFERENCES_NONE_NONE_NONE_NONE \
    1955                 :            :     SQL_GET_REFERENCES \
    1956                 :            :     SQL_GET_REFERENCES_ORDER_NO_PTABLE
    1957                 :            : 
    1958                 :            : #define SQL_GET_REFERENCES_SOME_NONE_NONE_NONE \
    1959                 :            :     SQL_GET_REFERENCES \
    1960                 :            :     SQL_GET_REFERENCES_PSCHEMA \
    1961                 :            :     SQL_GET_REFERENCES_ORDER_NO_PTABLE
    1962                 :            : 
    1963                 :            : #define SQL_GET_REFERENCES_NONE_SOME_NONE_NONE \
    1964                 :            :     SQL_GET_REFERENCES \
    1965                 :            :     SQL_GET_REFERENCES_PTABLE \
    1966                 :            :     SQL_GET_REFERENCES_ORDER_SOME_PTABLE
    1967                 :            : 
    1968                 :            : #define SQL_GET_REFERENCES_SOME_SOME_NONE_NONE \
    1969                 :            :     SQL_GET_REFERENCES \
    1970                 :            :     SQL_GET_REFERENCES_PSCHEMA \
    1971                 :            :     SQL_GET_REFERENCES_PTABLE \
    1972                 :            :     SQL_GET_REFERENCES_ORDER_SOME_PTABLE
    1973                 :            : 
    1974                 :            : #define SQL_GET_REFERENCES_NONE_NONE_SOME_NONE \
    1975                 :            :     SQL_GET_REFERENCES \
    1976                 :            :     SQL_GET_REFERENCES_FSCHEMA \
    1977                 :            :     SQL_GET_REFERENCES_ORDER_NO_PTABLE
    1978                 :            : 
    1979                 :            : #define SQL_GET_REFERENCES_NONE_NONE_NONE_SOME \
    1980                 :            :     SQL_GET_REFERENCES \
    1981                 :            :     SQL_GET_REFERENCES_FTABLE \
    1982                 :            :     SQL_GET_REFERENCES_ORDER_NO_PTABLE
    1983                 :            : 
    1984                 :            : #define SQL_GET_REFERENCES_NONE_NONE_SOME_SOME \
    1985                 :            :     SQL_GET_REFERENCES \
    1986                 :            :     SQL_GET_REFERENCES_FSCHEMA \
    1987                 :            :     SQL_GET_REFERENCES_FTABLE \
    1988                 :            :     SQL_GET_REFERENCES_ORDER_NO_PTABLE
    1989                 :            : 
    1990                 :            : #define SQL_GET_REFERENCES_SOME_NONE_SOME_NONE \
    1991                 :            :     SQL_GET_REFERENCES \
    1992                 :            :     SQL_GET_REFERENCES_PSCHEMA \
    1993                 :            :     SQL_GET_REFERENCES_FSCHEMA \
    1994                 :            :     SQL_GET_REFERENCES_ORDER_NO_PTABLE
    1995                 :            : 
    1996                 :            : #define SQL_GET_REFERENCES_SOME_NONE_NONE_SOME \
    1997                 :            :     SQL_GET_REFERENCES \
    1998                 :            :     SQL_GET_REFERENCES_PSCHEMA \
    1999                 :            :     SQL_GET_REFERENCES_FTABLE \
    2000                 :            :     SQL_GET_REFERENCES_ORDER_NO_PTABLE
    2001                 :            : 
    2002                 :            : #define SQL_GET_REFERENCES_SOME_NONE_SOME_SOME \
    2003                 :            :     SQL_GET_REFERENCES \
    2004                 :            :     SQL_GET_REFERENCES_PSCHEMA \
    2005                 :            :     SQL_GET_REFERENCES_FSCHEMA \
    2006                 :            :     SQL_GET_REFERENCES_FTABLE \
    2007                 :            :     SQL_GET_REFERENCES_ORDER_NO_PTABLE
    2008                 :            : 
    2009                 :            : #define SQL_GET_REFERENCES_NONE_SOME_SOME_NONE \
    2010                 :            :     SQL_GET_REFERENCES \
    2011                 :            :     SQL_GET_REFERENCES_PTABLE \
    2012                 :            :     SQL_GET_REFERENCES_FSCHEMA \
    2013                 :            :     SQL_GET_REFERENCES_ORDER_SOME_PTABLE
    2014                 :            : 
    2015                 :            : #define SQL_GET_REFERENCES_NONE_SOME_NONE_SOME \
    2016                 :            :     SQL_GET_REFERENCES \
    2017                 :            :     SQL_GET_REFERENCES_PTABLE \
    2018                 :            :     SQL_GET_REFERENCES_FTABLE \
    2019                 :            :     SQL_GET_REFERENCES_ORDER_SOME_PTABLE
    2020                 :            : 
    2021                 :            : #define SQL_GET_REFERENCES_NONE_SOME_SOME_SOME \
    2022                 :            :     SQL_GET_REFERENCES \
    2023                 :            :     SQL_GET_REFERENCES_PTABLE \
    2024                 :            :     SQL_GET_REFERENCES_FSCHEMA \
    2025                 :            :     SQL_GET_REFERENCES_FTABLE \
    2026                 :            :     SQL_GET_REFERENCES_ORDER_SOME_PTABLE
    2027                 :            : 
    2028                 :            : #define SQL_GET_REFERENCES_SOME_SOME_SOME_NONE \
    2029                 :            :     SQL_GET_REFERENCES \
    2030                 :            :     SQL_GET_REFERENCES_PSCHEMA \
    2031                 :            :     SQL_GET_REFERENCES_PTABLE \
    2032                 :            :     SQL_GET_REFERENCES_FSCHEMA \
    2033                 :            :     SQL_GET_REFERENCES_ORDER_SOME_PTABLE
    2034                 :            : 
    2035                 :            : #define SQL_GET_REFERENCES_SOME_SOME_NONE_SOME \
    2036                 :            :     SQL_GET_REFERENCES \
    2037                 :            :     SQL_GET_REFERENCES_PSCHEMA \
    2038                 :            :     SQL_GET_REFERENCES_PTABLE \
    2039                 :            :     SQL_GET_REFERENCES_FTABLE \
    2040                 :            :     SQL_GET_REFERENCES_ORDER_SOME_PTABLE
    2041                 :            : 
    2042                 :            : #define SQL_GET_REFERENCES_SOME_SOME_SOME_SOME \
    2043                 :            :     SQL_GET_REFERENCES \
    2044                 :            :     SQL_GET_REFERENCES_PSCHEMA \
    2045                 :            :     SQL_GET_REFERENCES_PTABLE \
    2046                 :            :     SQL_GET_REFERENCES_FSCHEMA \
    2047                 :            :     SQL_GET_REFERENCES_FTABLE \
    2048                 :            :     SQL_GET_REFERENCES_ORDER_SOME_PTABLE
    2049                 :            : 
    2050                 :          0 : void DatabaseMetaData::init_getReferences_stmt ()
    2051                 :            : {
    2052                 :          0 :     m_getReferences_stmt[0]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_NONE_NONE_NONE_NONE ));
    2053                 :          0 :     m_getReferences_stmt[1]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_SOME_NONE_NONE_NONE ));
    2054                 :          0 :     m_getReferences_stmt[2]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_NONE_SOME_NONE_NONE ));
    2055                 :          0 :     m_getReferences_stmt[3]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_SOME_SOME_NONE_NONE ));
    2056                 :          0 :     m_getReferences_stmt[4]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_NONE_NONE_SOME_NONE ));
    2057                 :          0 :     m_getReferences_stmt[5]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_SOME_NONE_SOME_NONE ));
    2058                 :          0 :     m_getReferences_stmt[6]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_NONE_SOME_SOME_NONE ));
    2059                 :          0 :     m_getReferences_stmt[7]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_SOME_SOME_SOME_NONE ));
    2060                 :          0 :     m_getReferences_stmt[8]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_NONE_NONE_NONE_SOME ));
    2061                 :          0 :     m_getReferences_stmt[9]  = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_SOME_NONE_NONE_SOME ));
    2062                 :          0 :     m_getReferences_stmt[10] = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_NONE_SOME_NONE_SOME ));
    2063                 :          0 :     m_getReferences_stmt[11] = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_SOME_SOME_NONE_SOME ));
    2064                 :          0 :     m_getReferences_stmt[12] = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_NONE_NONE_SOME_SOME ));
    2065                 :          0 :     m_getReferences_stmt[13] = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_SOME_NONE_SOME_SOME ));
    2066                 :          0 :     m_getReferences_stmt[14] = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_NONE_SOME_SOME_SOME ));
    2067                 :          0 :     m_getReferences_stmt[15] = m_origin->prepareStatement(ASCII_STR( SQL_GET_REFERENCES_SOME_SOME_SOME_SOME ));
    2068                 :          0 : }
    2069                 :            : 
    2070                 :          0 : void DatabaseMetaData::init_getPrivs_stmt ()
    2071                 :            : {
    2072                 :          0 :     rtl::OUStringBuffer sSQL(300);
    2073                 :            :     sSQL.append( ASCII_STR(
    2074                 :            :             " SELECT dp.TABLE_CAT, dp.TABLE_SCHEM, dp.TABLE_NAME, dp.GRANTOR, pr.rolname AS GRANTEE, dp.privilege, dp.is_grantable "
    2075                 :            :             " FROM ("
    2076                 :            :             "  SELECT table_catalog AS TABLE_CAT, table_schema AS TABLE_SCHEM, table_name,"
    2077                 :            :             "         grantor, grantee, privilege_type AS PRIVILEGE, is_grantable"
    2078                 :          0 :             "  FROM information_schema.table_privileges") );
    2079                 :          0 :     if ( PQserverVersion( m_pSettings->pConnection ) < 90200 )
    2080                 :            :         // information_schema.table_privileges does not fill in default ACLs when no ACL
    2081                 :            :         // assume default ACL is "owner has all privileges" and add it
    2082                 :            :         sSQL.append( ASCII_STR(
    2083                 :            :             " UNION "
    2084                 :            :             "  SELECT current_database() AS TABLE_CAT, pn.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME,"
    2085                 :            :             "         ro.rolname AS GRANTOR, rg.rolname AS GRANTEE, p.privilege, 'YES' AS is_grantable"
    2086                 :            :             "  FROM pg_catalog.pg_class c,"
    2087                 :            :             "       (VALUES ('SELECT'), ('INSERT'), ('UPDATE'), ('DELETE'), ('TRUNCATE'), ('REFERENCES'), ('TRIGGER')) p (privilege),"
    2088                 :            :             "       pg_catalog.pg_roles ro,"
    2089                 :            :             "       (  SELECT oid, rolname FROM pg_catalog.pg_roles"
    2090                 :            :             "         UNION ALL"
    2091                 :            :             "          VALUES (0::oid, 'PUBLIC')"
    2092                 :            :             "       ) AS rg (oid, rolname),"
    2093                 :            :             "       pg_catalog.pg_namespace pn"
    2094                 :            :             "  WHERE c.relkind IN ('r', 'v') AND c.relacl IS NULL AND pg_has_role(rg.oid, c.relowner, 'USAGE')"
    2095                 :          0 :             "        AND c.relowner=ro.oid AND c.relnamespace = pn.oid") );
    2096                 :            :     sSQL.append( ASCII_STR(
    2097                 :            :             " ) dp,"
    2098                 :            :             " (SELECT oid, rolname FROM pg_catalog.pg_roles UNION ALL VALUES (0, 'PUBLIC')) pr"
    2099                 :            :             " WHERE table_schem LIKE ? AND table_name LIKE ? AND (dp.grantee = 'PUBLIC' OR pg_has_role(pr.oid, dp.grantee, 'USAGE'))"
    2100                 :          0 :             " ORDER BY table_schem, table_name, privilege" ) );
    2101                 :            : 
    2102                 :          0 :     m_getTablePrivs_stmt = m_origin->prepareStatement( sSQL.makeStringAndClear() );
    2103                 :            : 
    2104                 :            :     sSQL.append( ASCII_STR(
    2105                 :            :             " SELECT dp.TABLE_CAT, dp.TABLE_SCHEM, dp.TABLE_NAME, dp.COLUMN_NAME, dp.GRANTOR, pr.rolname AS GRANTEE, dp.PRIVILEGE, dp.IS_GRANTABLE FROM ("
    2106                 :            :             "  SELECT table_catalog AS TABLE_CAT, table_schema AS TABLE_SCHEM, table_name, column_name,"
    2107                 :            :             "         grantor, grantee, privilege_type AS PRIVILEGE, is_grantable"
    2108                 :          0 :             "  FROM information_schema.column_privileges") );
    2109                 :          0 :     if ( PQserverVersion( m_pSettings->pConnection ) < 90200 )
    2110                 :            :         // information_schema.table_privileges does not fill in default ACLs when no ACL
    2111                 :            :         // assume default ACL is "owner has all privileges" and add it
    2112                 :            :         sSQL.append( ASCII_STR(
    2113                 :            :             " UNION "
    2114                 :            :             "  SELECT current_database() AS TABLE_CAT, pn.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, a.attname AS column_name,"
    2115                 :            :             "         ro.rolname AS GRANTOR, rg.rolname AS GRANTEE, p.privilege, 'YES' AS is_grantable"
    2116                 :            :             "  FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a,"
    2117                 :            :             "       (VALUES ('SELECT'), ('INSERT'), ('UPDATE'), ('REFERENCES')) p (privilege),"
    2118                 :            :             "       pg_catalog.pg_roles ro,"
    2119                 :            :             "       (  SELECT oid, rolname FROM pg_catalog.pg_roles"
    2120                 :            :             "         UNION ALL"
    2121                 :            :             "          VALUES (0::oid, 'PUBLIC')"
    2122                 :            :             "       ) AS rg (oid, rolname),"
    2123                 :            :             "       pg_catalog.pg_namespace pn"
    2124                 :            :             "  WHERE c.relkind IN ('r', 'v') AND c.relacl IS NULL AND pg_has_role(rg.oid, c.relowner, 'USAGE')"
    2125                 :          0 :             "        AND c.relowner=ro.oid AND c.relnamespace = pn.oid AND a.attrelid = c.oid AND a.attnum > 0") );
    2126                 :            :     sSQL.append( ASCII_STR(
    2127                 :            :             " ) dp,"
    2128                 :            :             " (SELECT oid, rolname FROM pg_catalog.pg_roles UNION ALL VALUES (0, 'PUBLIC')) pr"
    2129                 :            :             " WHERE table_schem = ? AND table_name = ? AND column_name LIKE ? AND (dp.grantee = 'PUBLIC' OR pg_has_role(pr.oid, dp.grantee, 'USAGE'))"
    2130                 :          0 :             " ORDER BY column_name, privilege" ) );
    2131                 :            : 
    2132                 :          0 :     m_getColumnPrivs_stmt = m_origin->prepareStatement( sSQL.makeStringAndClear() );
    2133                 :          0 : }
    2134                 :            : 
    2135                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getImportedExportedKeys(
    2136                 :            :     const Any& /* primaryCatalog */,
    2137                 :            :     const OUString& primarySchema,
    2138                 :            :     const OUString& primaryTable,
    2139                 :            :     const Any& /* foreignCatalog */,
    2140                 :            :     const OUString& foreignSchema,
    2141                 :            :     const OUString& foreignTable ) throw (SQLException, RuntimeException)
    2142                 :            : {
    2143                 :          0 :     unsigned int i = 0;
    2144                 :          0 :     if ( ! primarySchema.isEmpty() )
    2145                 :          0 :         i |=  0x01;
    2146                 :          0 :     if ( ! primaryTable.isEmpty() )
    2147                 :          0 :         i |=  0x02;
    2148                 :          0 :     if ( ! foreignSchema.isEmpty() )
    2149                 :          0 :         i |=  0x04;
    2150                 :          0 :     if ( ! foreignTable.isEmpty() )
    2151                 :          0 :         i |=  0x08;
    2152                 :            : 
    2153                 :          0 :     Reference< XPreparedStatement > stmt = m_getReferences_stmt[i];
    2154                 :          0 :     Reference< XParameters > param ( stmt, UNO_QUERY_THROW );
    2155                 :            : 
    2156                 :          0 :     unsigned int j = 1;
    2157                 :          0 :     if ( i & 0x01 )
    2158                 :          0 :         param->setString( j++, primarySchema );
    2159                 :          0 :     if ( i & 0x02 )
    2160                 :          0 :         param->setString( j++, primaryTable  );
    2161                 :          0 :     if ( i & 0x04 )
    2162                 :          0 :         param->setString( j++, foreignSchema );
    2163                 :          0 :     if ( i & 0x08 )
    2164                 :          0 :         param->setString( j++, foreignTable  );
    2165                 :            : 
    2166                 :          0 :     Reference< XResultSet > rs = stmt->executeQuery();
    2167                 :            : 
    2168                 :          0 :     return rs;
    2169                 :            : }
    2170                 :            : 
    2171                 :            : 
    2172                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getImportedKeys(
    2173                 :            :     const ::com::sun::star::uno::Any& catalog,
    2174                 :            :     const OUString& schema,
    2175                 :            :     const OUString& table ) throw (SQLException, RuntimeException)
    2176                 :            : {
    2177                 :          0 :     return getImportedExportedKeys(Any(), OUString(), OUString(), catalog, schema, table);
    2178                 :            : }
    2179                 :            : 
    2180                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getExportedKeys(
    2181                 :            :     const ::com::sun::star::uno::Any& catalog,
    2182                 :            :     const OUString& schema,
    2183                 :            :     const OUString& table ) throw (SQLException, RuntimeException)
    2184                 :            : {
    2185                 :          0 :     return getImportedExportedKeys(catalog, schema, table, Any(), OUString(), OUString());
    2186                 :            : }
    2187                 :            : 
    2188                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getCrossReference(
    2189                 :            :     const ::com::sun::star::uno::Any& primaryCatalog,
    2190                 :            :     const OUString& primarySchema,
    2191                 :            :     const OUString& primaryTable,
    2192                 :            :     const ::com::sun::star::uno::Any& foreignCatalog,
    2193                 :            :     const OUString& foreignSchema,
    2194                 :            :     const OUString& foreignTable ) throw (SQLException, RuntimeException)
    2195                 :            : {
    2196                 :          0 :     return getImportedExportedKeys( primaryCatalog, primarySchema, primaryTable, foreignCatalog, foreignSchema, foreignTable );
    2197                 :            : }
    2198                 :            : 
    2199                 :            : 
    2200                 :            : struct TypeInfoByDataTypeSorter
    2201                 :            : {
    2202                 :          0 :     bool operator () ( const Sequence< Any > & a, const Sequence< Any > & b )
    2203                 :            :     {
    2204                 :          0 :         OUString valueA;
    2205                 :          0 :         OUString valueB;
    2206                 :          0 :         a[1 /*DATA_TYPE*/] >>= valueA;
    2207                 :          0 :         b[1 /*DATA_TYPE*/] >>= valueB;
    2208                 :          0 :         if( valueB.toInt32() == valueA.toInt32() )
    2209                 :            :         {
    2210                 :          0 :             OUString nameA;
    2211                 :          0 :             OUString nameB;
    2212                 :          0 :             a[0 /*TYPE_NAME*/] >>= nameA;
    2213                 :          0 :             b[0 /*TYPE_NAME*/] >>= nameB;
    2214                 :          0 :             if( nameA.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "int4" ) ) == 0 )
    2215                 :          0 :                 return 1;
    2216                 :          0 :             if( nameB.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "int4" ) ) == 0 )
    2217                 :          0 :                 return 0;
    2218                 :          0 :             return nameA.compareTo( nameB ) < 0;
    2219                 :            :         }
    2220                 :            : 
    2221                 :          0 :         return valueA.toInt32() < valueB.toInt32();
    2222                 :            : //         sal_Int32 valueA;
    2223                 :            : //         sal_Int32 valueB;
    2224                 :            : //         a[1 /*DATA_TYPE*/] >>= valueA;
    2225                 :            : //         b[1 /*DATA_TYPE*/] >>= valueB;
    2226                 :            : //         if( valueB == valueA )
    2227                 :            : //         {
    2228                 :            : //             OUString nameA;
    2229                 :            : //             OUString nameB;
    2230                 :            : //             a[0 /*TYPE_NAME*/] >>= nameA;
    2231                 :            : //             b[0 /*TYPE_NAME*/] >>= nameB;
    2232                 :            : //             return nameA.compareTo( nameB ) < 0;
    2233                 :            : //         }
    2234                 :            : 
    2235                 :            : //         return valueA < valueB;
    2236                 :            :     }
    2237                 :            : };
    2238                 :            : 
    2239                 :          0 : static sal_Int32 calcSearchable( sal_Int32 dataType )
    2240                 :            : {
    2241                 :          0 :     sal_Int32 ret = com::sun::star::sdbc::ColumnSearch::FULL;
    2242                 :          0 :     if( com::sun::star::sdbc::DataType::BINARY == dataType ||
    2243                 :            :         com::sun::star::sdbc::DataType::VARBINARY == dataType ||
    2244                 :            :         com::sun::star::sdbc::DataType::LONGVARBINARY == dataType )
    2245                 :          0 :         ret = com::sun::star::sdbc::ColumnSearch::NONE;
    2246                 :            : 
    2247                 :          0 :     return ret;
    2248                 :            : }
    2249                 :            : 
    2250                 :          0 : static sal_Int32 getMaxScale( sal_Int32 dataType )
    2251                 :            : {
    2252                 :            :     // LEM TODO: review, see where used, see JDBC, ...
    2253                 :          0 :     sal_Int32 ret = 0;
    2254                 :          0 :     if( dataType == com::sun::star::sdbc::DataType::NUMERIC )
    2255                 :          0 :         ret = 1000; // see pg-docs DataType/numeric
    2256                 :            : //     else if( dataType == DataType::DOUBLE )
    2257                 :            : //         ret = 308;
    2258                 :            : //     else if( dataType == DataType::FLOAT )
    2259                 :            : //         ret =
    2260                 :          0 :     return ret;
    2261                 :            : }
    2262                 :            : 
    2263                 :            : 
    2264                 :            : struct RawType
    2265                 :            : {
    2266                 :            :     const char * typeName;
    2267                 :            :     const char * createParam;
    2268                 :            :     sal_Int32    sdbcType;
    2269                 :            :     sal_Int32    precision;
    2270                 :            :     sal_Int32    nullable;
    2271                 :            :     bool         caseSensitive;
    2272                 :            :     sal_Int32    searchable;
    2273                 :            : };
    2274                 :            : 
    2275                 :          0 : static void pgTypeInfo2ResultSet(
    2276                 :            :      SequenceAnyVector &vec,
    2277                 :            :      const Reference< XResultSet > &rs )
    2278                 :            : {
    2279                 :            :     static const sal_Int32 TYPE_NAME = 0;  // string Type name
    2280                 :            :     static const sal_Int32 DATA_TYPE = 1;  // short SQL data type from java.sql.Types
    2281                 :            :     static const sal_Int32 PRECISION = 2;  // long maximum precision
    2282                 :            :     static const sal_Int32 CREATE_PARAMS = 5; // string => parameters used in creating the type (may be NULL )
    2283                 :            :     static const sal_Int32 NULLABLE  = 6;  // short ==> can you use NULL for this type?
    2284                 :            :                                            // - NO_NULLS - does not allow NULL values
    2285                 :            :                                            // - NULLABLE - allows NULL values
    2286                 :            :                                            // - NULLABLE_UNKNOWN - nullability unknown
    2287                 :            : 
    2288                 :            :     static const sal_Int32 CASE_SENSITIVE = 7; // boolean==> is it case sensitive
    2289                 :            :     static const sal_Int32 SEARCHABLE = 8;  // short ==>; can you use
    2290                 :            :                                             // "WHERE" based on this type:
    2291                 :            :                                             //   - NONE - No support
    2292                 :            :                                             //   - CHAR - Only supported with WHERE .. LIKE
    2293                 :            :                                             //   - BASIC - Supported except for WHERE .. LIKE
    2294                 :            :                                             //   - FULL - Supported for all WHERE ..
    2295                 :            :     static const sal_Int32 UNSIGNED_ATTRIBUTE = 9; // boolean ==> is it unsigned?
    2296                 :            :     static const sal_Int32 FIXED_PREC_SCALE = 10; // boolean ==> can it be a money value?
    2297                 :            :     static const sal_Int32 AUTO_INCREMENT = 11; // boolean ==> can it be used for
    2298                 :            :                                                 // an auto-increment value?
    2299                 :            :     static const sal_Int32 MINIMUM_SCALE = 13; // short ==> minimum scale supported
    2300                 :            :     static const sal_Int32 MAXIMUM_SCALE = 14; // short ==> maximum scale supported
    2301                 :            :     static const sal_Int32 NUM_PREC_RADIX = 17; // long ==> usually 2 or 10
    2302                 :            : 
    2303                 :            :     /*  not filled so far
    2304                 :            :         3. LITERAL_PREFIX string ==> prefix used to quote a literal
    2305                 :            :                                      (may be <NULL/>)
    2306                 :            :         4, LITERAL_SUFFIX string ==> suffix used to quote a literal
    2307                 :            :                                     (may be <NULL/>)
    2308                 :            :         5. CREATE_PARAMS string ==> parameters used in creating thw type (may be <NULL/>)
    2309                 :            :         12. LOCAL_TYPE_NAME  string ==> localized version of type name (may be <NULL/>)
    2310                 :            :         15, SQL_DATA_TYPE long ==> unused
    2311                 :            :         16. SQL_DATETIME_SUB long ==> unused
    2312                 :            :      */
    2313                 :          0 :     Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    2314                 :          0 :     while( rs->next() )
    2315                 :            :     {
    2316                 :          0 :         Sequence< Any > row(18);
    2317                 :            : 
    2318                 :          0 :         sal_Int32 dataType =typeNameToDataType(xRow->getString(5),xRow->getString(2));
    2319                 :          0 :         sal_Int32 precision = xRow->getString(3).toInt32();
    2320                 :            : 
    2321                 :          0 :         if( dataType == com::sun::star::sdbc::DataType::CHAR  ||
    2322                 :            :             ( dataType == com::sun::star::sdbc::DataType::VARCHAR &&
    2323                 :          0 :               xRow->getString(TYPE_NAME+1).equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("varchar")) ) )
    2324                 :            :         {
    2325                 :            :             // reflect varchar as varchar with upper limit !
    2326                 :            :             //NOTE: the sql spec requires varchar to have an upper limit, however
    2327                 :            :             //      in postgresql the upper limit is optional, no limit means unlimited
    2328                 :            :             //      length (=1GB).
    2329                 :          0 :             precision = 0x40000000; // about 1 GB, see character type docs in postgresql
    2330                 :          0 :             row[CREATE_PARAMS] <<= ASCII_STR( "length" );
    2331                 :            :         }
    2332                 :          0 :         else if( dataType == com::sun::star::sdbc::DataType::NUMERIC )
    2333                 :            :         {
    2334                 :          0 :             precision = 1000;
    2335                 :          0 :             row[CREATE_PARAMS] <<= ASCII_STR( "length, scale" );
    2336                 :            :         }
    2337                 :            : 
    2338                 :          0 :         row[TYPE_NAME] <<= xRow->getString(1);
    2339                 :          0 :         row[DATA_TYPE] <<= OUString::valueOf(dataType);
    2340                 :          0 :         row[PRECISION] <<= OUString::valueOf( precision );
    2341                 :          0 :         sal_Int32 nullable = xRow->getBoolean(4) ?
    2342                 :            :             com::sun::star::sdbc::ColumnValue::NO_NULLS :
    2343                 :          0 :             com::sun::star::sdbc::ColumnValue::NULLABLE;
    2344                 :          0 :         row[NULLABLE] <<= OUString::valueOf(nullable);
    2345                 :          0 :         row[CASE_SENSITIVE] <<= OUString::valueOf((sal_Int32)1);
    2346                 :          0 :         row[SEARCHABLE] <<= OUString::valueOf( calcSearchable( dataType ) );
    2347                 :          0 :         row[UNSIGNED_ATTRIBUTE] <<= ASCII_STR( "0" ); //
    2348                 :          0 :         if( com::sun::star::sdbc::DataType::INTEGER == dataType ||
    2349                 :            :             com::sun::star::sdbc::DataType::BIGINT == dataType )
    2350                 :          0 :             row[AUTO_INCREMENT] <<= ASCII_STR( "1" );     // TODO
    2351                 :            :         else
    2352                 :          0 :             row[AUTO_INCREMENT] <<= ASCII_STR( "0" );     // TODO
    2353                 :          0 :         row[MINIMUM_SCALE] <<= ASCII_STR( "0" );      // TODO: what is this ?
    2354                 :          0 :         row[MAXIMUM_SCALE] <<= OUString::valueOf( getMaxScale( dataType ) );
    2355                 :          0 :         row[NUM_PREC_RADIX] <<= ASCII_STR( "10" );    // TODO: what is this ?
    2356                 :            :         (void)FIXED_PREC_SCALE;
    2357                 :          0 :         vec.push_back( row );
    2358                 :          0 :     }
    2359                 :            : 
    2360                 :          0 : }
    2361                 :            : 
    2362                 :            : 
    2363                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTypeInfo(  )
    2364                 :            :     throw (SQLException, RuntimeException)
    2365                 :            : {
    2366                 :            :     // Note: Indexes start at 0 (in the API doc, they start at 1)
    2367                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    2368                 :          0 :     checkClosed();
    2369                 :            : 
    2370                 :          0 :     if( isLog( m_pSettings, LogLevel::INFO ) )
    2371                 :            :     {
    2372                 :          0 :         log( m_pSettings, LogLevel::INFO, "DatabaseMetaData::getTypeInfo() got called" );
    2373                 :            :     }
    2374                 :            : 
    2375                 :          0 :     Reference< XStatement > statement = m_origin->createStatement();
    2376                 :          0 :     Reference< XResultSet > rs = statement->executeQuery(
    2377                 :            :         ASCII_STR(
    2378                 :            :           "SELECT pg_type.typname AS typname," //1
    2379                 :            :           "pg_type.typtype AS typtype,"        //2
    2380                 :            :           "pg_type.typlen AS typlen,"          //3
    2381                 :            :           "pg_type.typnotnull AS typnotnull,"  //4
    2382                 :            :           "pg_type.typname AS typname "        //5
    2383                 :            :           "FROM pg_type "
    2384                 :            :           "WHERE pg_type.typtype = 'b' "
    2385                 :            :           "OR pg_type.typtype = 'p'"
    2386                 :          0 :             ) );
    2387                 :            : 
    2388                 :          0 :     SequenceAnyVector vec;
    2389                 :          0 :     pgTypeInfo2ResultSet( vec, rs );
    2390                 :            : 
    2391                 :            :     // check for domain types
    2392                 :          0 :     rs = statement->executeQuery(
    2393                 :            :      ASCII_STR(
    2394                 :            :         "SELECT t1.typname as typname,"
    2395                 :            :         "t2.typtype AS typtype,"
    2396                 :            :         "t2.typlen AS typlen,"
    2397                 :            :         "t2.typnotnull AS typnotnull,"
    2398                 :            :         "t2.typname as realtypname "
    2399                 :            :         "FROM pg_type as t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype=t2.oid "
    2400                 :          0 :         "WHERE t1.typtype = 'd'" ) );
    2401                 :          0 :     pgTypeInfo2ResultSet( vec, rs );
    2402                 :            : 
    2403                 :          0 :     std::sort( vec.begin(), vec.end(), TypeInfoByDataTypeSorter() );
    2404                 :            : 
    2405                 :            :     return new SequenceResultSet(
    2406                 :            :         m_refMutex,
    2407                 :            :         *this,
    2408                 :          0 :         getStatics().typeinfoColumnNames,
    2409                 :            :         sequence_of_vector(vec),
    2410                 :            :         m_pSettings->tc,
    2411                 :          0 :         &( getStatics().typeInfoMetaData ));
    2412                 :            : }
    2413                 :            : 
    2414                 :            : 
    2415                 :          0 : static sal_Int32 seqContains( const Sequence< sal_Int32 > &seq, sal_Int32 value )
    2416                 :            : {
    2417                 :          0 :     sal_Int32 ret = -1;
    2418                 :          0 :     for( int i = 0; i < seq.getLength(); i ++ )
    2419                 :            :     {
    2420                 :          0 :         if( seq[i] == value )
    2421                 :            :         {
    2422                 :          0 :             ret = i;
    2423                 :          0 :             break;
    2424                 :            :         }
    2425                 :            :     }
    2426                 :          0 :     return ret;
    2427                 :            : }
    2428                 :            : 
    2429                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getIndexInfo(
    2430                 :            :     const ::com::sun::star::uno::Any& catalog,
    2431                 :            :     const OUString& schema,
    2432                 :            :     const OUString& table,
    2433                 :            :     sal_Bool unique,
    2434                 :            :     sal_Bool approximate ) throw (SQLException, RuntimeException)
    2435                 :            : {
    2436                 :            :     (void) catalog; (void) approximate;
    2437                 :            :     //LEM TODO: review
    2438                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    2439                 :          0 :     checkClosed();
    2440                 :            : 
    2441                 :            :     /*
    2442                 :            :        1. TABLE_CAT string -> table catalog (may be NULL )
    2443                 :            :        2. TABLE_SCHEM string -> table schema (may be NULL )
    2444                 :            :        3. TABLE_NAME string -> table name
    2445                 :            :        4. NON_UNIQUE boolean -> Can index values be non-unique?
    2446                 :            :                                 false when TYPE is tableIndexStatistic
    2447                 :            :        5. INDEX_QUALIFIER string -> index catalog (may be NULL );
    2448                 :            :                                 NULL when TYPE is tableIndexStatistic
    2449                 :            :        6. INDEX_NAME string -> index name; NULL when TYPE is tableIndexStatistic
    2450                 :            :        7. TYPE short -> index type:
    2451                 :            :               * 0 - this identifies table statistics that are returned
    2452                 :            :                     in conjuction with a table's index descriptions
    2453                 :            :               * CLUSTERED - this is a clustered index
    2454                 :            :               * HASHED - this is a hashed index
    2455                 :            :               * OTHER - this is some other style of index
    2456                 :            :        8. ORDINAL_POSITION short -> column sequence number within index;
    2457                 :            :                                     zero when TYPE is tableIndexStatistic
    2458                 :            :        9. COLUMN_NAME string -> column name; NULL when TYPE is tableIndexStatistic
    2459                 :            :       10. ASC_OR_DESC string -> column sort sequence, "A"= ascending,
    2460                 :            :                                 "D" = descending, may be NULL if sort sequence
    2461                 :            :                                 is not supported; NULL when TYPE is tableIndexStatistic
    2462                 :            :       11. CARDINALITY long -> When TYPE is tableIndexStatistic, then this is
    2463                 :            :                               the number of rows in the table; otherwise, it
    2464                 :            :                               is the number of unique values in the index.
    2465                 :            :       12. PAGES long -> When TYPE is tableIndexStatisic then this is
    2466                 :            :                         the number of pages used for the table, otherwise
    2467                 :            :                         it is the number of pages used for the current index.
    2468                 :            :       13. FILTER_CONDITION string -> Filter condition, if any. (may be NULL )
    2469                 :            : 
    2470                 :            :     */
    2471                 :            :     static const sal_Int32 C_SCHEMA = 1;
    2472                 :            :     static const sal_Int32 C_TABLENAME = 2;
    2473                 :            :     static const sal_Int32 C_INDEXNAME = 3;
    2474                 :            :     static const sal_Int32 C_IS_CLUSTERED = 4;
    2475                 :            :     static const sal_Int32 C_IS_UNIQUE = 5;
    2476                 :            :     static const sal_Int32 C_IS_PRIMARY = 6;
    2477                 :            :     static const sal_Int32 C_COLUMNS = 7;
    2478                 :            : 
    2479                 :            :     static const sal_Int32 R_TABLE_SCHEM = 1;
    2480                 :            :     static const sal_Int32 R_TABLE_NAME = 2;
    2481                 :            :     static const sal_Int32 R_NON_UNIQUE = 3;
    2482                 :            :     static const sal_Int32 R_INDEX_NAME = 5;
    2483                 :            :     static const sal_Int32 R_TYPE = 6;
    2484                 :            :     static const sal_Int32 R_ORDINAL_POSITION = 7;
    2485                 :            :     static const sal_Int32 R_COLUMN_NAME = 8;
    2486                 :            : 
    2487                 :          0 :     Reference< XPreparedStatement > stmt = m_origin->prepareStatement(
    2488                 :            :         ASCII_STR(
    2489                 :            :             "SELECT nspname, "          // 1
    2490                 :            :                    "pg_class.relname, " // 2
    2491                 :            :                    "class2.relname, "   // 3
    2492                 :            :                    "indisclustered, "   // 4
    2493                 :            :                    "indisunique, "      // 5
    2494                 :            :                    "indisprimary, "     // 6
    2495                 :            :                    "indkey "            // 7
    2496                 :            :             "FROM pg_index INNER JOIN pg_class ON indrelid = pg_class.oid "
    2497                 :            :                           "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
    2498                 :            :                           "INNER JOIN pg_class as class2 ON pg_index.indexrelid = class2.oid "
    2499                 :          0 :             "WHERE nspname = ? AND pg_class.relname = ?" ) );
    2500                 :            : 
    2501                 :          0 :     Reference< XParameters > param ( stmt, UNO_QUERY_THROW );
    2502                 :          0 :     param->setString( 1, schema );
    2503                 :          0 :     param->setString( 2, table );
    2504                 :          0 :     Reference< XResultSet > rs = stmt->executeQuery();
    2505                 :          0 :     Reference< XRow > xRow ( rs, UNO_QUERY_THROW );
    2506                 :            : 
    2507                 :          0 :     SequenceAnyVector vec;
    2508                 :          0 :     while( rs->next() )
    2509                 :            :     {
    2510                 :          0 :         Sequence< sal_Int32 > columns = parseIntArray( xRow->getString(C_COLUMNS) );
    2511                 :          0 :         Reference< XPreparedStatement > columnsStmt = m_origin->prepareStatement(
    2512                 :            :             ASCII_STR(
    2513                 :            :                 "SELECT attnum, attname "
    2514                 :            :                 "FROM pg_attribute "
    2515                 :            :                 "     INNER JOIN pg_class ON attrelid = pg_class.oid "
    2516                 :            :                 "     INNER JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid "
    2517                 :          0 :                 "     WHERE pg_namespace.nspname=?  AND pg_class.relname=?" ) );
    2518                 :          0 :         Reference< XParameters > paramColumn ( columnsStmt, UNO_QUERY_THROW );
    2519                 :          0 :         OUString currentSchema = xRow->getString( C_SCHEMA );
    2520                 :          0 :         OUString currentTable = xRow->getString( C_TABLENAME );
    2521                 :          0 :         OUString currentIndexName = xRow->getString( C_INDEXNAME );
    2522                 :          0 :         sal_Bool isNonUnique = ! xRow->getBoolean( C_IS_UNIQUE );
    2523                 :          0 :         sal_Bool isPrimary = xRow->getBoolean( C_IS_PRIMARY );
    2524                 :            :         (void)isPrimary;
    2525                 :          0 :         sal_Int32 indexType =  xRow->getBoolean( C_IS_CLUSTERED ) ?
    2526                 :            :             com::sun::star::sdbc::IndexType::CLUSTERED :
    2527                 :          0 :             com::sun::star::sdbc::IndexType::HASHED;
    2528                 :            : 
    2529                 :          0 :         paramColumn->setString( C_SCHEMA, currentSchema );
    2530                 :          0 :         paramColumn->setString( C_TABLENAME, currentTable );
    2531                 :            : 
    2532                 :          0 :         Reference< XResultSet > rsColumn = columnsStmt->executeQuery();
    2533                 :          0 :         Reference< XRow > rowColumn( rsColumn, UNO_QUERY_THROW );
    2534                 :          0 :         while( rsColumn->next() )
    2535                 :            :         {
    2536                 :          0 :             sal_Int32 pos = seqContains( columns, rowColumn->getInt( 1 ) );
    2537                 :          0 :             if( pos >= 0 && ( ! isNonUnique || !  unique ) )
    2538                 :            :             {
    2539                 :          0 :                 Sequence< Any > result( 13 );
    2540                 :          0 :                 result[R_TABLE_SCHEM] = makeAny(currentSchema);
    2541                 :          0 :                 result[R_TABLE_NAME] = makeAny(currentTable);
    2542                 :          0 :                 result[R_INDEX_NAME] = makeAny(currentIndexName);
    2543                 :          0 :                 result[R_NON_UNIQUE] =
    2544                 :          0 :                     Any( &isNonUnique, getBooleanCppuType() );
    2545                 :          0 :                 result[R_TYPE] = makeAny( indexType );
    2546                 :          0 :                 result[R_COLUMN_NAME] = makeAny( rowColumn->getString(2) );
    2547                 :          0 :                 sal_Int32 nPos = ((sal_Int32)pos+1); // MSVC++ nonsense
    2548                 :          0 :                 result[R_ORDINAL_POSITION] = makeAny( nPos );
    2549                 :          0 :                 vec.push_back( result );
    2550                 :            :             }
    2551                 :            :         }
    2552                 :          0 :     }
    2553                 :            :     return new SequenceResultSet(
    2554                 :          0 :         m_refMutex, *this, getStatics().indexinfoColumnNames,
    2555                 :            :         sequence_of_vector(vec),
    2556                 :          0 :         m_pSettings->tc );
    2557                 :            : }
    2558                 :            : 
    2559                 :          0 : sal_Bool DatabaseMetaData::supportsResultSetType( sal_Int32 setType )
    2560                 :            :     throw (SQLException, RuntimeException)
    2561                 :            : {
    2562                 :          0 :     if ( setType == com::sun::star::sdbc::ResultSetType::SCROLL_SENSITIVE )
    2563                 :          0 :         return sal_False;
    2564                 :            :     else
    2565                 :          0 :         return sal_True;
    2566                 :            : }
    2567                 :            : 
    2568                 :          0 : sal_Bool DatabaseMetaData::supportsResultSetConcurrency(
    2569                 :            :     sal_Int32 setType, sal_Int32 concurrency ) throw (SQLException, RuntimeException)
    2570                 :            : {
    2571                 :            :     (void) concurrency;
    2572                 :          0 :     if ( ! supportsResultSetType( setType ) )
    2573                 :          0 :         return sal_False;
    2574                 :            :     else
    2575                 :          0 :         return sal_True;
    2576                 :            : }
    2577                 :            : 
    2578                 :          0 : sal_Bool DatabaseMetaData::ownUpdatesAreVisible( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2579                 :            : {
    2580                 :          0 :     return sal_True;
    2581                 :            : }
    2582                 :            : 
    2583                 :          0 : sal_Bool DatabaseMetaData::ownDeletesAreVisible( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2584                 :            : {
    2585                 :          0 :     return sal_True;
    2586                 :            : }
    2587                 :            : 
    2588                 :          0 : sal_Bool DatabaseMetaData::ownInsertsAreVisible( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2589                 :            : {
    2590                 :          0 :     return sal_True;
    2591                 :            : }
    2592                 :            : 
    2593                 :          0 : sal_Bool DatabaseMetaData::othersUpdatesAreVisible( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2594                 :            : {
    2595                 :          0 :     return sal_False;
    2596                 :            : }
    2597                 :            : 
    2598                 :          0 : sal_Bool DatabaseMetaData::othersDeletesAreVisible( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2599                 :            : {
    2600                 :          0 :     return sal_False;
    2601                 :            : }
    2602                 :            : 
    2603                 :          0 : sal_Bool DatabaseMetaData::othersInsertsAreVisible( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2604                 :            : {
    2605                 :          0 :     return sal_False;
    2606                 :            : }
    2607                 :            : 
    2608                 :          0 : sal_Bool DatabaseMetaData::updatesAreDetected( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2609                 :            : {
    2610                 :          0 :     return sal_False;
    2611                 :            : }
    2612                 :            : 
    2613                 :          0 : sal_Bool DatabaseMetaData::deletesAreDetected( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2614                 :            : {
    2615                 :          0 :     return sal_False;
    2616                 :            : }
    2617                 :          0 : sal_Bool DatabaseMetaData::insertsAreDetected( sal_Int32 /* setType */ ) throw (SQLException, RuntimeException)
    2618                 :            : {
    2619                 :          0 :     return sal_False;
    2620                 :            : }
    2621                 :            : 
    2622                 :          0 : sal_Bool DatabaseMetaData::supportsBatchUpdates(  ) throw (SQLException, RuntimeException)
    2623                 :            : {
    2624                 :          0 :     return sal_True;
    2625                 :            : }
    2626                 :            : 
    2627                 :          0 : ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getUDTs( const ::com::sun::star::uno::Any& catalog, const OUString& schemaPattern, const OUString& typeNamePattern, const ::com::sun::star::uno::Sequence< sal_Int32 >& types ) throw (SQLException, RuntimeException)
    2628                 :            : {
    2629                 :            :     (void) catalog; (void) schemaPattern; (void) typeNamePattern; (void) types;
    2630                 :            :     //LEM TODO: implement! See JDBC driver
    2631                 :          0 :     MutexGuard guard( m_refMutex->mutex );
    2632                 :          0 :     checkClosed();
    2633                 :            :     return new SequenceResultSet(
    2634                 :          0 :         m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc );
    2635                 :            : }
    2636                 :            : 
    2637                 :          0 : ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > DatabaseMetaData::getConnection()
    2638                 :            :     throw (SQLException, RuntimeException)
    2639                 :            : {
    2640                 :          0 :     return m_origin;
    2641                 :            : }
    2642                 :            : }

Generated by: LCOV version 1.10