1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * Effective License of whole file:
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.
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.
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,
20 * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
22 * The Contents of this file are made available subject to the terms of
23 * the GNU Lesser General Public License Version 2.1
25 * Copyright: 2000 by Sun Microsystems, Inc.
27 * Contributor(s): Joerg Budischewski
29 * All parts contributed on or after August 2011:
31 * This Source Code Form is subject to the terms of the Mozilla Public
32 * License, v. 2.0. If a copy of the MPL was not distributed with this
33 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
35 * Some portions were adapted from JDBC PostgreSQL driver:
37 * Copyright (c) 2004-2008, PostgreSQL Global Development Group
39 * Licence of original JDBC driver code:
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions are met:
44 * 1. Redistributions of source code must retain the above copyright notice,
45 * this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright notice,
47 * this list of conditions and the following disclaimer in the documentation
48 * and/or other materials provided with the distribution.
49 * 3. Neither the name of the PostgreSQL Global Development Group nor the names
50 * of its contributors may be used to endorse or promote products derived
51 * from this software without specific prior written permission.
53 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
54 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
57 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
58 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
59 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
61 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63 * POSSIBILITY OF SUCH DAMAGE.
65 ************************************************************************/
68 #include "pq_databasemetadata.hxx"
69 #include "pq_driver.hxx"
70 #include "pq_sequenceresultset.hxx"
71 #include "pq_statics.hxx"
72 #include "pq_tools.hxx"
74 #include <rtl/ustrbuf.hxx>
76 #include <com/sun/star/sdbc/TransactionIsolation.hpp>
77 #include <com/sun/star/sdbc/ResultSetType.hpp>
78 #include <com/sun/star/sdbc/XPreparedStatement.hpp>
79 #include <com/sun/star/sdbc/XParameters.hpp>
80 #include <com/sun/star/sdbc/DataType.hpp>
81 #include <com/sun/star/sdbc/IndexType.hpp>
82 #include <com/sun/star/sdbc/ColumnValue.hpp>
83 #include <com/sun/star/sdbc/ColumnSearch.hpp>
84 #include <com/sun/star/sdbc/KeyRule.hpp>
85 #include <com/sun/star/sdbc/Deferrability.hpp>
87 using ::osl::MutexGuard
;
90 using namespace com::sun::star::sdbc
;
92 using com::sun::star::uno::RuntimeException
;
93 using com::sun::star::uno::Reference
;
94 using com::sun::star::uno::Sequence
;
95 using com::sun::star::uno::Any
;
96 using com::sun::star::uno::makeAny
;
97 using com::sun::star::uno::UNO_QUERY
;
98 using com::sun::star::uno::UNO_QUERY_THROW
;
100 namespace pq_sdbc_driver
105 com::sun::star::uno::Sequence
< com::sun::star::uno::Any
>
109 #define QUOTEME(X) #X
110 #define STRINGIFY(X) QUOTEME(X)
112 // These are pre-processor versions of KeyRule.idl declarations
113 // These are inherited from JDBC, and thus won't change anytime soon.
114 // Having them as pre-processor definitions allows to include them
115 // into compile-time strings (through STRINGIFY), which can be passed to ASCII_STR.
116 // That is without resorting to horrendeous hacks in template meta-programming.
117 #define KEYRULE_CASCADE 0
118 #define KEYRULE_RESTRICT 1
119 #define KEYRULE_SET_NULL 2
120 #define KEYRULE_NO_ACTION 4
121 #define KEYRULE_SET_DEFAULT 4
122 // Ditto for Deferrability.idl
123 #define DEFERRABILITY_INITIALLY_DEFERRED 5
124 #define DEFERRABILITY_INITIALLY_IMMEDIATE 6
125 #define DEFERRABILITY_NONE 7
127 void DatabaseMetaData::checkClosed()
128 throw (SQLException
, RuntimeException
)
132 DatabaseMetaData::DatabaseMetaData(
133 const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
134 const ::com::sun::star::uno::Reference
< com::sun::star::sdbc::XConnection
> & origin
,
135 ConnectionSettings
*pSettings
)
136 : m_refMutex( refMutex
),
137 m_pSettings( pSettings
),
139 m_getIntSetting_stmt ( m_origin
->prepareStatement("SELECT setting FROM pg_catalog.pg_settings WHERE name=?") )
141 init_getReferences_stmt();
142 init_getPrivs_stmt();
145 sal_Bool
DatabaseMetaData::allProceduresAreCallable( ) throw (SQLException
, RuntimeException
, std::exception
)
151 sal_Bool
DatabaseMetaData::allTablesAreSelectable( ) throw (SQLException
, RuntimeException
, std::exception
)
156 OUString
DatabaseMetaData::getURL( ) throw (SQLException
, RuntimeException
, std::exception
)
159 // LEM TODO: implement
163 OUString
DatabaseMetaData::getUserName( ) throw (SQLException
, RuntimeException
, std::exception
)
165 return m_pSettings
->user
;
168 sal_Bool
DatabaseMetaData::isReadOnly( ) throw (SQLException
, RuntimeException
, std::exception
)
174 sal_Bool
DatabaseMetaData::nullsAreSortedHigh( ) throw (SQLException
, RuntimeException
, std::exception
)
176 // Whether NULL values are considered, for sorting purposes, LARGER than any other value.
177 // Specification: http://download.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#nullsAreSortedHigh()
178 // PostgreSQL behaviour: http://www.postgresql.org/docs/9.1/static/queries-order.htlm
182 sal_Bool
DatabaseMetaData::nullsAreSortedLow( ) throw (SQLException
, RuntimeException
, std::exception
)
184 return ! nullsAreSortedHigh();
187 sal_Bool
DatabaseMetaData::nullsAreSortedAtStart( ) throw (SQLException
, RuntimeException
, std::exception
)
192 sal_Bool
DatabaseMetaData::nullsAreSortedAtEnd( ) throw (SQLException
, RuntimeException
, std::exception
)
197 OUString
DatabaseMetaData::getDatabaseProductName( ) throw (SQLException
, RuntimeException
, std::exception
)
199 return OUString("PostgreSQL");
202 OUString
DatabaseMetaData::getDatabaseProductVersion( ) throw (SQLException
, RuntimeException
, std::exception
)
204 return OUString::createFromAscii( PQparameterStatus( m_pSettings
->pConnection
, "server_version" ) );
206 OUString
DatabaseMetaData::getDriverName( ) throw (SQLException
, RuntimeException
, std::exception
)
208 return OUString("postgresql-sdbc");
211 OUString
DatabaseMetaData::getDriverVersion( ) throw (SQLException
, RuntimeException
, std::exception
)
213 return OUString(PQ_SDBC_DRIVER_VERSION
);
216 sal_Int32
DatabaseMetaData::getDriverMajorVersion( ) throw (RuntimeException
, std::exception
)
218 return PQ_SDBC_MAJOR
;
221 sal_Int32
DatabaseMetaData::getDriverMinorVersion( ) throw (RuntimeException
, std::exception
)
223 return PQ_SDBC_MINOR
;
226 sal_Bool
DatabaseMetaData::usesLocalFiles( ) throw (SQLException
, RuntimeException
, std::exception
)
229 // http://wiki.openoffice.org/wiki/Documentation/DevGuide/Database/XDatabaseMetaData_Interface
230 // says "Returns true when the catalog name of the
231 // database should not appear in the DatasourceBrowser
232 // of OpenOffice.org API, otherwise false is returned."
233 // So, hmmm, think about it.
237 sal_Bool
DatabaseMetaData::usesLocalFilePerTable( ) throw (SQLException
, RuntimeException
, std::exception
)
242 sal_Bool
DatabaseMetaData::supportsMixedCaseIdentifiers( ) throw (SQLException
, RuntimeException
, std::exception
)
247 sal_Bool
DatabaseMetaData::storesUpperCaseIdentifiers( ) throw (SQLException
, RuntimeException
, std::exception
)
252 sal_Bool
DatabaseMetaData::storesLowerCaseIdentifiers( ) throw (SQLException
, RuntimeException
, std::exception
)
258 sal_Bool
DatabaseMetaData::storesMixedCaseIdentifiers( ) throw (SQLException
, RuntimeException
, std::exception
)
264 sal_Bool
DatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw (SQLException
, RuntimeException
, std::exception
)
269 sal_Bool
DatabaseMetaData::storesUpperCaseQuotedIdentifiers( ) throw (SQLException
, RuntimeException
, std::exception
)
275 sal_Bool
DatabaseMetaData::storesLowerCaseQuotedIdentifiers( ) throw (SQLException
, RuntimeException
, std::exception
)
281 sal_Bool
DatabaseMetaData::storesMixedCaseQuotedIdentifiers( ) throw (SQLException
, RuntimeException
, std::exception
)
287 OUString
DatabaseMetaData::getIdentifierQuoteString( ) throw (SQLException
, RuntimeException
, std::exception
)
289 return OUString("\"");
292 OUString
DatabaseMetaData::getSQLKeywords( ) throw (SQLException
, RuntimeException
, std::exception
)
294 // In Java 6, this is all keywords that are not SQL:2003
295 // In Java 2 v1.4 and as per LibreOffice SDK doc, this is all keywords that are not SQL92
296 // I understand this to mean "reserved keywords" only.
297 // See http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html
298 // LEM TODO: consider using pg_get_keywords(), filter on catcode
303 "ASYMMETRIC," //SQL:2003
306 "CURRENT_CATALOG," //SQL:2008
307 "CURRENT_ROLE," //SQL:1999
308 "CURRENT_SCHEMA," //SQL:2008
313 "LIMIT," //SQL:1999; non-reserved in SQL:2003
314 "LOCALTIME," //SQL:1999
315 "LOCALTIMESTAMP," //SQL:1999
319 "PLACING," //non-reserved in SQL:2003
320 "RETURNING," //non-reserved in SQL:2008
321 "SIMILAR," //SQL:2003
327 OUString
DatabaseMetaData::getNumericFunctions( ) throw (SQLException
, RuntimeException
, std::exception
)
329 // See http://www.postgresql.org/docs/9.1/static/functions-math.html
330 // LEM TODO: Err... http://wiki.openoffice.org/wiki/Documentation/DevGuide/Database/Support_Scalar_Functions
331 // says this should be "Open Group CLI" names, not PostgreSQL names.
332 // Currently this is just a list of supported functions in PostgreSQL, with PostgreSQL names.
333 // And it is my job to map from Open Group CLI names/syntax to PostgreSQL names/syntax. Where? By parsing the SQL???
334 // Should look at what the JDBC driver is doing.
368 OUString
DatabaseMetaData::getStringFunctions( ) throw (SQLException
, RuntimeException
, std::exception
)
370 // See http://www.postgresql.org/docs/9.1/static/functions-string.html
399 "pg_client_encoding,"
405 "regexp_split_to_array,"
406 "regexp_split_to_table,"
422 OUString
DatabaseMetaData::getSystemFunctions( ) throw (SQLException
, RuntimeException
, std::exception
)
424 // See http://www.postgresql.org/docs/9.1/static/functions-info.html
425 // and http://www.postgresql.org/docs/9.1/static/functions-admin.html
439 "pg_is_other_temp_schema,"
440 "pg_listening_channels,"
442 "pg_postmaster_start_time,"
446 "has_any_column_privilege,"
447 "has_any_column_privilege,"
448 "has_any_column_privilege,"
449 "has_column_privilege,"
450 "has_database_privilege,"
451 "has_foreign_data_wrapper_privilege,"
452 "has_function_privilege,"
453 "has_language_privilege,"
454 "has_schema_privilege,"
455 "has_sequence_privilege,"
456 "has_server_privilege,"
457 "has_table_privilege,"
458 "has_tablespace_privilege,"
460 "pg_collation_is_visible,"
461 "pg_conversion_is_visible,"
462 "pg_function_is_visible,"
463 "pg_opclass_is_visible,"
464 "pg_operator_is_visible,"
465 "pg_table_is_visible,"
466 "pg_ts_config_is_visible,"
467 "pg_ts_dict_is_visible,"
468 "pg_ts_parser_is_visible,"
469 "pg_ts_template_is_visible,"
470 "pg_type_is_visible,"
472 "pg_describe_object,"
473 "pg_get_constraintdef,"
475 "pg_get_functiondef,"
476 "pg_get_function_arguments,"
477 "pg_get_function_identity_arguments,"
478 "pg_get_function_result,"
482 "pg_get_serial_sequence,"
486 "pg_options_to_table,"
487 "pg_tablespace_databases,"
493 "txid_current_snapshot,"
495 "txid_snapshot_xmax,"
496 "txid_snapshot_xmin,"
497 "txid_visible_in_snapshot,"
506 "pg_terminate_backend,"
507 "pg_create_restore_point,"
508 "pg_current_xlog_insert_location,"
509 "pg_current_xlog_location,"
514 "pg_xlogfile_name_offset,"
516 "pg_last_xlog_receive_location,"
517 "pg_last_xlog_replay_location,"
518 "pg_last_xact_replay_timestamp,"
519 "pg_is_xlog_replay_paused,"
520 "pg_xlog_replay_pause,"
521 "pg_xlog_replay_resume,"
528 "pg_tablespace_size,"
529 "pg_tablespace_size,"
530 "pg_total_relation_size,"
531 "pg_relation_filenode,"
532 "pg_relation_filepath,"
535 "pg_read_binary_file,"
538 "pg_advisory_lock_shared,"
539 "pg_advisory_unlock,"
540 "pg_advisory_unlock_all,"
541 "pg_advisory_unlock_shared,"
542 "pg_advisory_xact_lock,"
543 "pg_advisory_xact_lock_shared,"
544 "pg_try_advisory_lock,"
545 "pg_try_advisory_lock_shared,"
546 "pg_try_advisory_xact_lock,"
547 "pg_try_advisory_xact_lock_shared,"
551 OUString
DatabaseMetaData::getTimeDateFunctions( ) throw (SQLException
, RuntimeException
, std::exception
)
575 "statement_timestamp,"
577 "transaction_timestamp,"
580 OUString
DatabaseMetaData::getSearchStringEscape( ) throw (SQLException
, RuntimeException
, std::exception
)
582 return OUString("\\");
584 OUString
DatabaseMetaData::getExtraNameCharacters( ) throw (SQLException
, RuntimeException
, std::exception
)
586 return OUString("$");
589 sal_Bool
DatabaseMetaData::supportsAlterTableWithAddColumn( ) throw (SQLException
, RuntimeException
, std::exception
)
594 sal_Bool
DatabaseMetaData::supportsAlterTableWithDropColumn( ) throw (SQLException
, RuntimeException
, std::exception
)
599 sal_Bool
DatabaseMetaData::supportsColumnAliasing( ) throw (SQLException
, RuntimeException
, std::exception
)
604 sal_Bool
DatabaseMetaData::nullPlusNonNullIsNull( ) throw (SQLException
, RuntimeException
, std::exception
)
609 sal_Bool
DatabaseMetaData::supportsTypeConversion( ) throw (SQLException
, RuntimeException
, std::exception
)
611 // LEM: this is specifically whether the "CONVERT" function is supported
612 // It seems that in PostgreSQL, that function is only for string encoding, so no.
616 sal_Bool
DatabaseMetaData::supportsConvert( sal_Int32 fromType
, sal_Int32 toType
) throw (SQLException
, RuntimeException
, std::exception
)
618 (void) fromType
; (void) toType
;
622 sal_Bool
DatabaseMetaData::supportsTableCorrelationNames( ) throw (SQLException
, RuntimeException
, std::exception
)
624 // LEM: A correlation name is "bar" in "SELECT foo FROM qux [AS] bar WHERE ..."
629 sal_Bool
DatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw (SQLException
, RuntimeException
, std::exception
)
633 sal_Bool
DatabaseMetaData::supportsExpressionsInOrderBy( ) throw (SQLException
, RuntimeException
, std::exception
)
638 sal_Bool
DatabaseMetaData::supportsOrderByUnrelated( ) throw (SQLException
, RuntimeException
, std::exception
)
643 sal_Bool
DatabaseMetaData::supportsGroupBy( ) throw (SQLException
, RuntimeException
, std::exception
)
648 sal_Bool
DatabaseMetaData::supportsGroupByUnrelated( ) throw (SQLException
, RuntimeException
, std::exception
)
653 sal_Bool
DatabaseMetaData::supportsGroupByBeyondSelect( ) throw (SQLException
, RuntimeException
, std::exception
)
658 sal_Bool
DatabaseMetaData::supportsLikeEscapeClause( ) throw (SQLException
, RuntimeException
, std::exception
)
663 sal_Bool
DatabaseMetaData::supportsMultipleResultSets( ) throw (SQLException
, RuntimeException
, std::exception
)
668 sal_Bool
DatabaseMetaData::supportsMultipleTransactions( ) throw (SQLException
, RuntimeException
, std::exception
)
670 // Allows multiple transactions open at once (on different connections!)
674 sal_Bool
DatabaseMetaData::supportsNonNullableColumns( ) throw (SQLException
, RuntimeException
, std::exception
)
680 sal_Bool
DatabaseMetaData::supportsMinimumSQLGrammar( ) throw (SQLException
, RuntimeException
, std::exception
)
685 sal_Bool
DatabaseMetaData::supportsCoreSQLGrammar( ) throw (SQLException
, RuntimeException
, std::exception
)
687 // LEM: jdbc driver says not, although the comments in it seem old
688 // fdo#45249 Base query design won't use any aggregate function
689 // (except COUNT(*) unless we say yes, so say yes.
690 // Actually, Base assumes *also* support for aggregate functions "collect, fusion, intersection"
691 // as soon as supportsCoreSQLGrammar() returns true.
692 // Those are *not* Core SQL, though. They are in optional feature S271 "Basic multiset support"
696 sal_Bool
DatabaseMetaData::supportsExtendedSQLGrammar( ) throw (SQLException
, RuntimeException
, std::exception
)
701 sal_Bool
DatabaseMetaData::supportsANSI92EntryLevelSQL( ) throw (SQLException
, RuntimeException
, std::exception
)
706 sal_Bool
DatabaseMetaData::supportsANSI92IntermediateSQL( ) throw (SQLException
, RuntimeException
, std::exception
)
708 // LEM: jdbc driver says not, although the comments in it seem old
712 sal_Bool
DatabaseMetaData::supportsANSI92FullSQL( ) throw (SQLException
, RuntimeException
, std::exception
)
714 // LEM: jdbc driver says not, although the comments in it seem old
718 sal_Bool
DatabaseMetaData::supportsIntegrityEnhancementFacility( ) throw (SQLException
, RuntimeException
, std::exception
)
720 // LEM: jdbc driver says yes, although comment says they are not sure what this means...
724 sal_Bool
DatabaseMetaData::supportsOuterJoins( ) throw (SQLException
, RuntimeException
, std::exception
)
729 sal_Bool
DatabaseMetaData::supportsFullOuterJoins( ) throw (SQLException
, RuntimeException
, std::exception
)
734 sal_Bool
DatabaseMetaData::supportsLimitedOuterJoins( ) throw (SQLException
, RuntimeException
, std::exception
)
740 OUString
DatabaseMetaData::getSchemaTerm( ) throw (SQLException
, RuntimeException
, std::exception
)
742 return OUString("SCHEMA");
745 OUString
DatabaseMetaData::getProcedureTerm( ) throw (SQLException
, RuntimeException
, std::exception
)
747 return OUString("function");
750 OUString
DatabaseMetaData::getCatalogTerm( ) throw (SQLException
, RuntimeException
, std::exception
)
752 return OUString("DATABASE");
755 sal_Bool
DatabaseMetaData::isCatalogAtStart( ) throw (SQLException
, RuntimeException
, std::exception
)
760 OUString
DatabaseMetaData::getCatalogSeparator( ) throw (SQLException
, RuntimeException
, std::exception
)
762 return OUString(".");
765 sal_Bool
DatabaseMetaData::supportsSchemasInDataManipulation( ) throw (SQLException
, RuntimeException
, std::exception
)
770 sal_Bool
DatabaseMetaData::supportsSchemasInProcedureCalls( ) throw (SQLException
, RuntimeException
, std::exception
)
775 sal_Bool
DatabaseMetaData::supportsSchemasInTableDefinitions( ) throw (SQLException
, RuntimeException
, std::exception
)
780 sal_Bool
DatabaseMetaData::supportsSchemasInIndexDefinitions( ) throw (SQLException
, RuntimeException
, std::exception
)
785 sal_Bool
DatabaseMetaData::supportsSchemasInPrivilegeDefinitions( ) throw (SQLException
, RuntimeException
, std::exception
)
790 sal_Bool
DatabaseMetaData::supportsCatalogsInDataManipulation( ) throw (SQLException
, RuntimeException
, std::exception
)
795 sal_Bool
DatabaseMetaData::supportsCatalogsInProcedureCalls( ) throw (SQLException
, RuntimeException
, std::exception
)
800 sal_Bool
DatabaseMetaData::supportsCatalogsInTableDefinitions( ) throw (SQLException
, RuntimeException
, std::exception
)
806 sal_Bool
DatabaseMetaData::supportsCatalogsInIndexDefinitions( ) throw (SQLException
, RuntimeException
, std::exception
)
812 sal_Bool
DatabaseMetaData::supportsCatalogsInPrivilegeDefinitions( ) throw (SQLException
, RuntimeException
, std::exception
)
818 // LEM TODO: positioned (through cursor) updates and deletes seem
819 // to be supported; see {UPDATE,DELETE} /table/ (...) WHERE CURRENT OF /cursor_name/" syntax
820 // and http://www.postgresql.org/docs/9.1/static/view-pg-cursors.html
821 // http://www.postgresql.org/docs/9.1/static/libpq-example.html actually uses a cursor :)
822 sal_Bool
DatabaseMetaData::supportsPositionedDelete( ) throw (SQLException
, RuntimeException
, std::exception
)
824 // LEM: jdbc driver says not, although the comments in it seem old
828 sal_Bool
DatabaseMetaData::supportsPositionedUpdate( ) throw (SQLException
, RuntimeException
, std::exception
)
830 // LEM: jdbc driver says not, although the comments in it seem old
835 sal_Bool
DatabaseMetaData::supportsSelectForUpdate( ) throw (SQLException
, RuntimeException
, std::exception
)
841 sal_Bool
DatabaseMetaData::supportsStoredProcedures( ) throw (SQLException
, RuntimeException
, std::exception
)
847 sal_Bool
DatabaseMetaData::supportsSubqueriesInComparisons( ) throw (SQLException
, RuntimeException
, std::exception
)
852 sal_Bool
DatabaseMetaData::supportsSubqueriesInExists( ) throw (SQLException
, RuntimeException
, std::exception
)
857 sal_Bool
DatabaseMetaData::supportsSubqueriesInIns( ) throw (SQLException
, RuntimeException
, std::exception
)
862 sal_Bool
DatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw (SQLException
, RuntimeException
, std::exception
)
864 // LEM: jdbc driver says yes, although comment says they don't know what this means...
868 sal_Bool
DatabaseMetaData::supportsCorrelatedSubqueries( ) throw (SQLException
, RuntimeException
, std::exception
)
872 sal_Bool
DatabaseMetaData::supportsUnion( ) throw (SQLException
, RuntimeException
, std::exception
)
877 sal_Bool
DatabaseMetaData::supportsUnionAll( ) throw (SQLException
, RuntimeException
, std::exception
)
882 sal_Bool
DatabaseMetaData::supportsOpenCursorsAcrossCommit( ) throw (SQLException
, RuntimeException
, std::exception
)
887 sal_Bool
DatabaseMetaData::supportsOpenCursorsAcrossRollback( ) throw (SQLException
, RuntimeException
, std::exception
)
892 sal_Bool
DatabaseMetaData::supportsOpenStatementsAcrossCommit( ) throw (SQLException
, RuntimeException
, std::exception
)
896 sal_Bool
DatabaseMetaData::supportsOpenStatementsAcrossRollback( ) throw (SQLException
, RuntimeException
, std::exception
)
901 sal_Int32
DatabaseMetaData::getMaxBinaryLiteralLength( ) throw (SQLException
, RuntimeException
, std::exception
)
906 sal_Int32
DatabaseMetaData::getMaxCharLiteralLength( ) throw (SQLException
, RuntimeException
, std::exception
)
911 // Copied / adapted / simplified from JDBC driver
912 sal_Int32
DatabaseMetaData::getIntSetting(const OUString
& settingName
)
913 throw (::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
915 MutexGuard
guard( m_refMutex
->mutex
);
917 Reference
< XParameters
> params(m_getIntSetting_stmt
, UNO_QUERY_THROW
);
918 params
->setString(1, settingName
);
919 Reference
< XResultSet
> rs
= m_getIntSetting_stmt
->executeQuery();
920 Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
921 OSL_VERIFY(rs
->next());
922 OSL_ENSURE(rs
->isFirst(), "postgresql-sdbc DatabaseMetaData getIntSetting not on first row");
923 OSL_ENSURE(rs
->isLast(), "postgresql-sdbc DatabaseMetaData getIntSetting not on last row");
924 return xRow
->getInt(1);
927 sal_Int32
DatabaseMetaData::getMaxNameLength()
928 throw (::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
930 if ( m_pSettings
->maxNameLen
== 0)
931 m_pSettings
->maxNameLen
= getIntSetting( "max_identifier_length" );
932 OSL_ENSURE(m_pSettings
->maxNameLen
, "postgresql-sdbc: maxNameLen is zero");
933 return m_pSettings
->maxNameLen
;
936 sal_Int32
DatabaseMetaData::getMaxIndexKeys()
937 throw (::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
939 if ( m_pSettings
->maxIndexKeys
== 0)
940 m_pSettings
->maxIndexKeys
= getIntSetting("max_index_keys");
941 OSL_ENSURE(m_pSettings
->maxIndexKeys
, "postgresql-sdbc: maxIndexKeys is zero");
942 return m_pSettings
->maxIndexKeys
;
945 sal_Int32
DatabaseMetaData::getMaxColumnNameLength( ) throw (SQLException
, RuntimeException
, std::exception
)
947 return getMaxNameLength();
950 sal_Int32
DatabaseMetaData::getMaxColumnsInGroupBy( ) throw (SQLException
, RuntimeException
, std::exception
)
955 sal_Int32
DatabaseMetaData::getMaxColumnsInIndex( ) throw (SQLException
, RuntimeException
, std::exception
)
957 return getMaxIndexKeys();
960 sal_Int32
DatabaseMetaData::getMaxColumnsInOrderBy( ) throw (SQLException
, RuntimeException
, std::exception
)
965 sal_Int32
DatabaseMetaData::getMaxColumnsInSelect( ) throw (SQLException
, RuntimeException
, std::exception
)
970 sal_Int32
DatabaseMetaData::getMaxColumnsInTable( ) throw (SQLException
, RuntimeException
, std::exception
)
975 sal_Int32
DatabaseMetaData::getMaxConnections( ) throw (SQLException
, RuntimeException
, std::exception
)
977 // LEM: The JDBC driver returns an arbitrary 8192; truth is as much as OS / hardware supports
981 sal_Int32
DatabaseMetaData::getMaxCursorNameLength( ) throw (SQLException
, RuntimeException
, std::exception
) //TODO, don't know
983 return getMaxNameLength();
986 sal_Int32
DatabaseMetaData::getMaxIndexLength( ) throw (SQLException
, RuntimeException
, std::exception
) //TODO, don't know
988 // LEM: that's the index itself, not its name
992 sal_Int32
DatabaseMetaData::getMaxSchemaNameLength( ) throw (SQLException
, RuntimeException
, std::exception
)
994 return getMaxNameLength();
997 sal_Int32
DatabaseMetaData::getMaxProcedureNameLength( ) throw (SQLException
, RuntimeException
, std::exception
)
999 return getMaxNameLength();
1002 sal_Int32
DatabaseMetaData::getMaxCatalogNameLength( ) throw (SQLException
, RuntimeException
, std::exception
)
1004 return getMaxNameLength();
1007 sal_Int32
DatabaseMetaData::getMaxRowSize( ) throw (SQLException
, RuntimeException
, std::exception
)
1009 // jdbc driver says 1GB, but http://www.postgresql.org/about/ says 1.6TB
1010 // and that 1GB is the maximum _field_ size
1011 // The row limit does not fit into a sal_Int32
1015 sal_Bool
DatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw (SQLException
, RuntimeException
, std::exception
)
1017 // LEM: Err... PostgreSQL basically does not do BLOBs well
1018 // In any case, BLOBs do not change the maximal row length AFAIK
1022 sal_Int32
DatabaseMetaData::getMaxStatementLength( ) throw (SQLException
, RuntimeException
, std::exception
)
1024 // LEM: actually, that would be 2^sizeof(size_t)-1
1025 // on the server? on the client (because of libpq)? minimum of the two? not sure
1026 // Anyway, big, so say unlimited.
1030 sal_Int32
DatabaseMetaData::getMaxStatements( ) throw (SQLException
, RuntimeException
, std::exception
) //TODO, don't know
1035 sal_Int32
DatabaseMetaData::getMaxTableNameLength( ) throw (SQLException
, RuntimeException
, std::exception
)
1037 return getMaxNameLength();
1040 sal_Int32
DatabaseMetaData::getMaxTablesInSelect( ) throw (SQLException
, RuntimeException
, std::exception
)
1045 sal_Int32
DatabaseMetaData::getMaxUserNameLength( ) throw (SQLException
, RuntimeException
, std::exception
)
1047 return getMaxNameLength();
1050 sal_Int32
DatabaseMetaData::getDefaultTransactionIsolation( ) throw (SQLException
, RuntimeException
, std::exception
)
1052 return com::sun::star::sdbc::TransactionIsolation::READ_COMMITTED
;
1055 sal_Bool
DatabaseMetaData::supportsTransactions( ) throw (SQLException
, RuntimeException
, std::exception
)
1060 sal_Bool
DatabaseMetaData::supportsTransactionIsolationLevel( sal_Int32 level
) throw (SQLException
, RuntimeException
, std::exception
)
1062 if ( level
== com::sun::star::sdbc::TransactionIsolation::READ_COMMITTED
1063 || level
== com::sun::star::sdbc::TransactionIsolation::SERIALIZABLE
1064 || level
== com::sun::star::sdbc::TransactionIsolation::READ_UNCOMMITTED
1065 || level
== com::sun::star::sdbc::TransactionIsolation::REPEATABLE_READ
)
1071 sal_Bool
DatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions( )
1072 throw (SQLException
, RuntimeException
, std::exception
)
1077 sal_Bool
DatabaseMetaData::supportsDataManipulationTransactionsOnly( ) throw (SQLException
, RuntimeException
, std::exception
)
1082 sal_Bool
DatabaseMetaData::dataDefinitionCausesTransactionCommit( ) throw (SQLException
, RuntimeException
, std::exception
)
1087 sal_Bool
DatabaseMetaData::dataDefinitionIgnoredInTransactions( ) throw (SQLException
, RuntimeException
, std::exception
)
1092 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getProcedures(
1093 const ::com::sun::star::uno::Any
& catalog
,
1094 const OUString
& schemaPattern
,
1095 const OUString
& procedureNamePattern
) throw (SQLException
, RuntimeException
, std::exception
)
1097 (void) catalog
; (void) schemaPattern
; (void) procedureNamePattern
;
1098 // 1. PROCEDURE_CAT string => procedure catalog (may be NULL )
1099 // 2. PROCEDURE_SCHEM string => procedure schema (may be NULL )
1100 // 3. PROCEDURE_NAME string => procedure name
1101 // 4. reserved for future use
1102 // 5. reserved for future use
1103 // 6. reserved for future use
1104 // 7. REMARKS string => explanatory comment on the procedure
1105 // 8. PROCEDURE_TYPE short => kind of procedure:
1106 // * UNKNOWN - May return a result
1107 // * NO - Does not return a result
1108 // * RETURN - Returns a result
1110 // LEM TODO: implement
1111 // LEM TODO: at least fake the columns, even if no row.
1112 MutexGuard
guard( m_refMutex
->mutex
);
1114 return new SequenceResultSet(
1115 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1118 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getProcedureColumns(
1119 const ::com::sun::star::uno::Any
& catalog
,
1120 const OUString
& schemaPattern
,
1121 const OUString
& procedureNamePattern
,
1122 const OUString
& columnNamePattern
) throw (SQLException
, RuntimeException
, std::exception
)
1124 (void) catalog
; (void) schemaPattern
; (void) procedureNamePattern
; (void) columnNamePattern
;
1125 MutexGuard
guard( m_refMutex
->mutex
);
1127 // LEM TODO: implement
1128 // LEM TODO: at least fake the columns, even if no row.
1129 return new SequenceResultSet(
1130 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1133 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getTables(
1134 const ::com::sun::star::uno::Any
& catalog
,
1135 const OUString
& schemaPattern
,
1136 const OUString
& tableNamePattern
,
1137 const ::com::sun::star::uno::Sequence
< OUString
>& types
)
1138 throw (SQLException
, RuntimeException
, std::exception
)
1140 (void) catalog
; (void) types
;
1141 Statics
&statics
= getStatics();
1143 MutexGuard
guard( m_refMutex
->mutex
);
1146 if( isLog( m_pSettings
, LogLevel::INFO
) )
1148 OUStringBuffer
buf( 128 );
1149 buf
.appendAscii( "DatabaseMetaData::getTables got called with " );
1150 buf
.append( schemaPattern
);
1151 buf
.appendAscii( "." );
1152 buf
.append( tableNamePattern
);
1153 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
1155 // ignore catalog, as a single pq connection does not support multiple catalogs
1157 // LEM TODO: this does not give the right column names, not the right number of columns, etc.
1158 // Take "inspiration" from JDBC driver
1159 // Ah, this is used to create a XResultSet manually... Try to do it directly in SQL
1160 Reference
< XPreparedStatement
> statement
= m_origin
->prepareStatement(
1162 "DISTINCT ON (pg_namespace.nspname, relname ) " // avoid duplicates (pg_settings !)
1163 "pg_namespace.nspname, relname, relkind, pg_description.description "
1164 "FROM pg_namespace, pg_class LEFT JOIN pg_description ON pg_class.oid = pg_description.objoid "
1165 "WHERE relnamespace = pg_namespace.oid "
1166 "AND ( relkind = 'r' OR relkind = 'v') "
1167 "AND pg_namespace.nspname LIKE ? "
1168 "AND relname LIKE ? "
1169 // "ORDER BY pg_namespace.nspname || relname"
1172 Reference
< XParameters
> parameters( statement
, UNO_QUERY_THROW
);
1173 parameters
->setString( 1 , schemaPattern
);
1174 parameters
->setString( 2 , tableNamePattern
);
1176 Reference
< XResultSet
> rs
= statement
->executeQuery();
1177 Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1178 SequenceAnyVector vec
;
1182 Sequence
< Any
> row( 5 );
1184 row
[0] <<= m_pSettings
->catalog
;
1185 row
[1] <<= xRow
->getString( 1 );
1186 row
[2] <<= xRow
->getString( 2 );
1187 OUString type
= xRow
->getString(3);
1188 if( type
.equalsAscii( "r" ) )
1190 if( xRow
->getString(1).equalsAscii( "pg_catalog" ) )
1192 row
[3] <<= statics
.SYSTEM_TABLE
;
1196 row
[3] <<= statics
.TABLE
;
1199 else if( type
.equalsAscii( "v" ) )
1201 row
[3] <<= statics
.VIEW
;
1205 row
[3] <<= statics
.UNKNOWN
;
1207 row
[4] <<= xRow
->getString(4);
1209 // no description in postgresql AFAIK
1210 vec
.push_back( row
);
1212 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
1213 if( closeable
.is() )
1216 return new SequenceResultSet(
1217 m_refMutex
, *this, statics
.tablesRowNames
, sequence_of_vector(vec
), m_pSettings
->tc
);
1220 struct SortInternalSchemasLastAndPublicFirst
1222 bool operator () ( const Sequence
< Any
> & a
, const Sequence
< Any
> & b
)
1229 if( valueA
.startsWith( "public" ) )
1233 else if( valueB
.startsWith( "public" ) )
1237 else if( valueA
.startsWith( "pg_" ) &&
1238 valueB
.startsWith( "pg_" ) )
1240 ret
= valueA
.compareTo( valueB
) < 0; // sorts equal !
1242 else if( valueA
.startsWith( "pg_" ))
1244 ret
= false; // sorts last !
1246 else if( valueB
.startsWith( "pg_" ) )
1248 ret
= true; // sorts first !
1252 ret
= (valueA
.compareTo( valueB
) < 0);
1258 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getSchemas( )
1259 throw (SQLException
, RuntimeException
, std::exception
)
1261 MutexGuard
guard( m_refMutex
->mutex
);
1264 if( isLog( m_pSettings
, LogLevel::INFO
) )
1266 log( m_pSettings
, LogLevel::INFO
, "DatabaseMetaData::getSchemas() got called" );
1268 // <b>TABLE_SCHEM</b> string =&gt; schema name
1269 Reference
< XStatement
> statement
= m_origin
->createStatement();
1270 Reference
< XResultSet
> rs
= statement
->executeQuery(
1271 "SELECT nspname from pg_namespace" );
1272 // LEM TODO: look at JDBC driver and consider doing the same
1273 // in particular, excluding temporary schemas, but maybe better through pg_is_other_temp_schema(oid) OR == pg_my_temp_schema()
1275 Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1276 SequenceAnyVector vec
;
1279 Sequence
<Any
> row(1);
1280 row
[0] <<= xRow
->getString(1);
1281 vec
.push_back( row
);
1284 // sort public first, sort internal schemas last, sort rest in alphabetic order
1285 std::sort( vec
.begin(), vec
.end(), SortInternalSchemasLastAndPublicFirst() );
1287 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
1288 if( closeable
.is() )
1290 return new SequenceResultSet(
1291 m_refMutex
, *this, getStatics().schemaNames
, sequence_of_vector(vec
), m_pSettings
->tc
);
1294 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getCatalogs( )
1295 throw (SQLException
, RuntimeException
, std::exception
)
1297 // LEM TODO: return the current catalog like JDBC driver?
1298 // at least fake the columns, even if no content
1299 MutexGuard
guard( m_refMutex
->mutex
);
1301 return new SequenceResultSet(
1302 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1305 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getTableTypes( )
1306 throw (SQLException
, RuntimeException
, std::exception
)
1308 // LEM TODO: this can be made dynamic, see JDBC driver
1309 MutexGuard
guard( m_refMutex
->mutex
);
1311 return new SequenceResultSet(
1312 m_refMutex
, *this, getStatics().tableTypeNames
, getStatics().tableTypeData
,
1317 /** returns the constant from sdbc.DataType
1319 sal_Int32
typeNameToDataType( const OUString
&typeName
, const OUString
&typtype
)
1321 // sal_Int32 ret = com::sun::star::sdbc::DataType::DISTINCT;
1322 // map all unknown types to memo (longvarchar). This allows to show them in
1323 // string representation. Additionally, the edit-table-type-selection-box
1324 // is not so unuseable anymore.
1325 sal_Int32 ret
= com::sun::star::sdbc::DataType::LONGVARCHAR
;
1326 if( typtype
.equalsAscii( "b" ) )
1328 // as long as the OOo framework does not support arrays,
1329 // the user is better of with interpreting arrays as strings !
1330 // if( typeName.getLength() && '_' == typeName[0] )
1332 // its just a naming convention, but as long as we don't have anything better,
1333 // we take it as granted
1334 // ret = com::sun::star::sdbc::DataType::ARRAY;
1337 Statics
&statics
= getStatics();
1338 BaseTypeMap::iterator ii
= statics
.baseTypeMap
.find( typeName
);
1339 if( ii
!= statics
.baseTypeMap
.end() )
1344 else if( typtype
.equalsAscii( "c" ) )
1346 ret
= com::sun::star::sdbc::DataType::STRUCT
;
1348 else if( typtype
.equalsAscii( "d" ) )
1350 ret
= com::sun::star::sdbc::DataType::LONGVARCHAR
;
1356 inline bool isSystemColumn( sal_Int16 attnum
)
1362 // is not exported by the postgres header
1363 const static int PQ_VARHDRSZ
= sizeof( sal_Int32
);
1365 // Oh, quelle horreur
1366 // LEM TODO: Need to severely rewrite that!
1367 // should probably just "do the same" as ODBC or JDBC drivers...
1368 static void extractPrecisionAndScale(
1369 sal_Int32 dataType
, sal_Int32 atttypmod
, sal_Int32
*precision
, sal_Int32
*scale
)
1371 if( atttypmod
< PQ_VARHDRSZ
)
1380 case com::sun::star::sdbc::DataType::NUMERIC
:
1381 case com::sun::star::sdbc::DataType::DECIMAL
:
1383 *precision
= ( ( atttypmod
- PQ_VARHDRSZ
) >> 16 ) & 0xffff;
1384 *scale
= (atttypmod
- PQ_VARHDRSZ
) & 0xffff;
1388 *precision
= atttypmod
- PQ_VARHDRSZ
;
1394 struct DatabaseTypeDescription
1396 DatabaseTypeDescription()
1398 DatabaseTypeDescription( const OUString
&name
, const OUString
& type
) :
1402 DatabaseTypeDescription( const DatabaseTypeDescription
&source
) :
1403 typeName( source
.typeName
),
1404 typeType( source
.typeType
)
1406 DatabaseTypeDescription
& operator = ( const DatabaseTypeDescription
& source
)
1408 typeName
= source
.typeName
;
1409 typeType
= source
.typeType
;
1416 typedef ::boost::unordered_map
1419 DatabaseTypeDescription
,
1420 ::boost::hash
< sal_Int32
>,
1421 ::std::equal_to
< sal_Int32
>
1422 > Oid2DatabaseTypeDescriptionMap
;
1424 static void columnMetaData2DatabaseTypeDescription(
1425 Oid2DatabaseTypeDescriptionMap
&oidMap
,
1426 const Reference
< XResultSet
> &rs
,
1427 const Reference
< XStatement
> &stmt
)
1429 Reference
< XRow
> row( rs
, UNO_QUERY_THROW
);
1431 OUStringBuffer
queryBuf(128);
1432 queryBuf
.append( "SELECT oid,typtype,typname FROM pg_TYPE WHERE " );
1435 if( row
->getString( 9 ) == "d" && oidMap
.find( row
->getInt( 12 ) ) == oidMap
.end() )
1437 oidMap
[row
->getInt(12)] = DatabaseTypeDescription();
1439 queryBuf
.appendAscii( " OR " );
1440 queryBuf
.appendAscii( "oid = " );
1441 queryBuf
.append( row
->getInt(12 ), 10 );
1449 Reference
< XResultSet
> rsDomain
= stmt
->executeQuery( queryBuf
.makeStringAndClear() );
1450 row
= Reference
< XRow
>( rsDomain
, UNO_QUERY_THROW
);
1451 while( rsDomain
->next() )
1453 oidMap
[row
->getInt(1)] = DatabaseTypeDescription(row
->getString(3), row
->getString(2) );
1455 disposeNoThrow( stmt
);
1462 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getColumns(
1463 const ::com::sun::star::uno::Any
& catalog
,
1464 const OUString
& schemaPattern
,
1465 const OUString
& tableNamePattern
,
1466 const OUString
& columnNamePattern
) throw (SQLException
, RuntimeException
, std::exception
)
1469 // LEM TODO: review in comparison with JDBC driver
1470 Statics
&statics
= getStatics();
1473 MutexGuard
guard( m_refMutex
->mutex
);
1476 if( isLog( m_pSettings
, LogLevel::INFO
) )
1478 OUStringBuffer
buf( 128 );
1479 buf
.appendAscii( "DatabaseMetaData::getColumns got called with " );
1480 buf
.append( schemaPattern
);
1481 buf
.appendAscii( "." );
1482 buf
.append( tableNamePattern
);
1483 buf
.appendAscii( "." );
1484 buf
.append( columnNamePattern
);
1485 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
1488 // ignore catalog, as a single pq connection
1489 // does not support multiple catalogs anyway
1490 // We don't use information_schema.columns because it contains
1491 // only the columns the current user has any privilege over.
1493 // 1. TABLE_CAT string => table catalog (may be NULL)
1495 // 2. TABLE_SCHEM string => table schema (may be NULL)
1496 // => pg_namespace.nspname
1497 // 3. TABLE_NAME string => table name
1498 // => pg_class.relname
1499 // 4. COLUMN_NAME string => column name
1500 // => pg_attribure.attname
1501 // 5. DATA_TYPE short => SQL type from java.sql.Types
1502 // => pg_type.typname => sdbc.DataType
1503 // 6. TYPE_NAME string => Data source dependent type name, for a UDT the
1504 // type name is fully qualified
1505 // => pg_type.typname
1506 // 7. COLUMN_SIZE long => column size. For char or date types this is
1507 // the maximum number of characters, for numeric
1508 // or decimal types this is precision.
1509 // => pg_attribute.atttypmod
1510 // 8. BUFFER_LENGTH is not used.
1512 // 9. DECIMAL_DIGITS long => the number of fractional digits
1513 // => don't know ! TODO !
1514 // 10. NUM_PREC_RADIX long => Radix (typically either 10 or 2)
1516 // 11. NULLABLE long => is NULL allowed?
1517 // NO_NULLS - might not allow NULL values
1518 // NULABLE - definitely allows NULL values
1519 // NULLABLE_UNKNOWN - nullability unknown
1520 // => pg_attribute.attnotnull
1521 // 12. REMARKS string => comment describing column (may be NULL )
1522 // => pg_description.description
1523 // 13. COLUMN_DEF string => default value (may be NULL)
1524 // => pg_type.typdefault
1525 // 14. SQL_DATA_TYPE long => unused
1527 // 15. SQL_DATETIME_SUB long => unused
1529 // 16. CHAR_OCTET_LENGTH long => for char types the maximum number of
1530 // bytes in the column
1531 // => pg_type.typlen
1532 // 17. ORDINAL_POSITION int => index of column in table (starting at 1)
1533 // pg_attribute.attnum
1534 // 18. IS_NULLABLE string => "NO" means column definitely does not allow
1535 // NULL values; "YES" means the column might
1536 // allow NULL values. An empty string means
1538 // => pg_attribute.attnotnull
1540 Reference
< XPreparedStatement
> statement
= m_origin
->prepareStatement(
1541 "SELECT pg_namespace.nspname, " // 1
1542 "pg_class.relname, " // 2
1543 "pg_attribute.attname, " // 3
1544 "pg_type.typname, " // 4
1545 "pg_attribute.atttypmod, " // 5
1546 "pg_attribute.attnotnull, " // 6
1547 "pg_type.typdefault, " // 7
1548 "pg_type.typtype, " // 8
1549 "pg_attrdef.adsrc, " // 9
1550 "pg_description.description, " // 10
1551 "pg_type.typbasetype, " // 11
1552 "pg_attribute.attnum " // 12
1554 "pg_attribute LEFT JOIN pg_attrdef ON pg_attribute.attrelid = pg_attrdef.adrelid AND pg_attribute.attnum = pg_attrdef.adnum "
1555 "LEFT JOIN pg_description ON pg_attribute.attrelid = pg_description.objoid AND pg_attribute.attnum=pg_description.objsubid,"
1556 " pg_type, pg_namespace "
1557 "WHERE pg_attribute.attrelid = pg_class.oid "
1558 "AND pg_attribute.atttypid = pg_type.oid "
1559 "AND pg_class.relnamespace = pg_namespace.oid "
1560 "AND NOT pg_attribute.attisdropped "
1561 "AND pg_namespace.nspname LIKE ? "
1562 "AND pg_class.relname LIKE ? "
1563 "AND pg_attribute.attname LIKE ? "
1564 "ORDER BY pg_namespace.nspname, pg_class.relname, pg_attribute.attnum"
1567 Reference
< XParameters
> parameters( statement
, UNO_QUERY_THROW
);
1568 parameters
->setString( 1 , schemaPattern
);
1569 parameters
->setString( 2 , tableNamePattern
);
1570 parameters
->setString( 3 , columnNamePattern
);
1572 Reference
< XResultSet
> rs
= statement
->executeQuery();
1573 Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1574 SequenceAnyVector vec
;
1576 Oid2DatabaseTypeDescriptionMap domainMap
;
1577 Reference
< XStatement
> domainTypeStmt
= m_origin
->createStatement();
1578 columnMetaData2DatabaseTypeDescription( domainMap
, rs
, domainTypeStmt
);
1580 sal_uInt32
colNum(0);
1581 OUString
sSchema( "#invalid#" );
1582 OUString
sTable( "#invalid#" );
1586 if( m_pSettings
->showSystemColumns
|| ! isSystemColumn( xRow
->getShort( 12 ) ) )
1588 OUString
sNewSchema( xRow
->getString(1) );
1589 OUString
sNewTable( xRow
->getString(2) );
1590 if ( sNewSchema
!= sSchema
|| sNewTable
!= sTable
)
1593 sSchema
= sNewSchema
;
1598 sal_Int32 precision
, scale
, type
;
1599 Sequence
< Any
> row( 18 );
1600 row
[0] <<= m_pSettings
->catalog
;
1601 row
[1] <<= sNewSchema
;
1602 row
[2] <<= sNewTable
;
1603 row
[3] <<= xRow
->getString(3);
1604 if( xRow
->getString(8) == "d" )
1606 DatabaseTypeDescription
desc( domainMap
[xRow
->getInt(11)] );
1607 type
= typeNameToDataType( desc
.typeName
, desc
.typeType
);
1611 type
= typeNameToDataType( xRow
->getString(4), xRow
->getString(8) );
1613 extractPrecisionAndScale( type
, xRow
->getInt(5) , &precision
, &scale
);
1615 row
[5] <<= xRow
->getString(4);
1616 row
[6] <<= precision
;
1617 // row[7] BUFFER_LENGTH not used
1619 // row[9] RADIX TODO
1620 if( xRow
->getBoolean( 6 ) && ! isSystemColumn(xRow
->getInt( 12 )) )
1622 row
[10] <<= OUString::number(com::sun::star::sdbc::ColumnValue::NO_NULLS
);
1623 row
[17] <<= statics
.NO
;
1627 row
[10] <<= OUString::number(com::sun::star::sdbc::ColumnValue::NULLABLE
);
1628 row
[17] <<= statics
.YES
;
1631 row
[11] <<= xRow
->getString( 10 ); // comment
1632 row
[12] <<= xRow
->getString( 9 ); // COLUMN_DEF = pg_type.typdefault
1633 // row[13] SQL_DATA_TYPE not used
1634 // row[14] SQL_DATETIME_SUB not used
1635 row
[15] <<= precision
;
1636 row
[16] <<= colNum
;
1638 vec
.push_back( row
);
1641 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
1642 if( closeable
.is() )
1645 return new SequenceResultSet(
1646 m_refMutex
, *this, statics
.columnRowNames
, sequence_of_vector(vec
), m_pSettings
->tc
);
1649 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getColumnPrivileges(
1650 const ::com::sun::star::uno::Any
& catalog
,
1651 const OUString
& schema
,
1652 const OUString
& table
,
1653 const OUString
& columnNamePattern
) throw (SQLException
, RuntimeException
, std::exception
)
1657 MutexGuard
guard( m_refMutex
->mutex
);
1660 if( isLog( m_pSettings
, LogLevel::INFO
) )
1662 OUStringBuffer
buf( 128 );
1663 buf
.appendAscii( "DatabaseMetaData::getColumnPrivileges got called with " );
1664 buf
.append( schema
);
1665 buf
.appendAscii( "." );
1666 buf
.append( table
);
1667 buf
.appendAscii( "." );
1668 buf
.append( columnNamePattern
);
1669 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
1672 Reference
< XParameters
> parameters( m_getColumnPrivs_stmt
, UNO_QUERY_THROW
);
1673 parameters
->setString( 1 , schema
);
1674 parameters
->setString( 2 , table
);
1675 parameters
->setString( 3 , columnNamePattern
);
1677 Reference
< XResultSet
> rs
= m_getColumnPrivs_stmt
->executeQuery();
1682 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getTablePrivileges(
1683 const ::com::sun::star::uno::Any
& catalog
,
1684 const OUString
& schemaPattern
,
1685 const OUString
& tableNamePattern
) throw (SQLException
, RuntimeException
, std::exception
)
1688 MutexGuard
guard( m_refMutex
->mutex
);
1691 if( isLog( m_pSettings
, LogLevel::INFO
) )
1693 OUStringBuffer
buf( 128 );
1694 buf
.appendAscii( "DatabaseMetaData::getTablePrivileges got called with " );
1695 buf
.append( schemaPattern
);
1696 buf
.appendAscii( "." );
1697 buf
.append( tableNamePattern
);
1698 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
1701 Reference
< XParameters
> parameters( m_getTablePrivs_stmt
, UNO_QUERY_THROW
);
1702 parameters
->setString( 1 , schemaPattern
);
1703 parameters
->setString( 2 , tableNamePattern
);
1705 Reference
< XResultSet
> rs
= m_getTablePrivs_stmt
->executeQuery();
1710 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getBestRowIdentifier(
1711 const ::com::sun::star::uno::Any
& catalog
,
1712 const OUString
& schema
,
1713 const OUString
& table
,
1715 sal_Bool nullable
) throw (SQLException
, RuntimeException
, std::exception
)
1717 (void) catalog
; (void) schema
; (void) table
; (void) scope
; (void) nullable
;
1718 //LEM TODO: implement! See JDBC driver
1719 MutexGuard
guard( m_refMutex
->mutex
);
1721 return new SequenceResultSet(
1722 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1725 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getVersionColumns(
1726 const ::com::sun::star::uno::Any
& catalog
,
1727 const OUString
& schema
,
1728 const OUString
& table
) throw (SQLException
, RuntimeException
, std::exception
)
1730 (void) catalog
; (void) schema
; (void) table
;
1731 //LEM TODO: implement! See JDBC driver
1732 MutexGuard
guard( m_refMutex
->mutex
);
1734 return new SequenceResultSet(
1735 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1738 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getPrimaryKeys(
1739 const ::com::sun::star::uno::Any
& catalog
,
1740 const OUString
& schema
,
1741 const OUString
& table
) throw (SQLException
, RuntimeException
, std::exception
)
1745 MutexGuard
guard( m_refMutex
->mutex
);
1748 // 1. TABLE_CAT string => table catalog (may be NULL )
1749 // 2. TABLE_SCHEM string => table schema (may be NULL )
1750 // 3. TABLE_NAME string => table name
1751 // 4. COLUMN_NAME string => column name
1752 // 5. KEY_SEQ short => sequence number within primary key
1753 // 6. PK_NAME string => primary key name (may be NULL )
1755 if( isLog( m_pSettings
, LogLevel::INFO
) )
1757 OUStringBuffer
buf( 128 );
1758 buf
.appendAscii( "DatabaseMetaData::getPrimaryKeys got called with " );
1759 buf
.append( schema
);
1760 buf
.appendAscii( "." );
1761 buf
.append( table
);
1762 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
1765 Reference
< XPreparedStatement
> statement
= m_origin
->prepareStatement(
1766 "SELECT nmsp.nspname, "
1771 "FROM pg_constraint as con,pg_class as cl, pg_namespace as nmsp "
1772 "WHERE con.connamespace = nmsp.oid AND con.conrelid = cl.oid AND con.contype = 'p' "
1773 "AND nmsp.nspname LIKE ? AND cl.relname LIKE ?" );
1775 Reference
< XParameters
> parameters( statement
, UNO_QUERY_THROW
);
1776 parameters
->setString( 1 , schema
);
1777 parameters
->setString( 2 , table
);
1779 Reference
< XResultSet
> rs
= statement
->executeQuery();
1780 Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1781 SequenceAnyVector vec
;
1785 Sequence
< Any
> row( 6 );
1786 row
[0] <<= m_pSettings
->catalog
;
1787 row
[1] <<= xRow
->getString(1);
1788 row
[2] <<= xRow
->getString(2);
1789 OUString array
= xRow
->getString(3);
1790 row
[4] <<= xRow
->getString(5); // the relid
1791 row
[5] <<= xRow
->getString(4);
1794 // now retrieve the columns information
1795 // unfortunately, postgresql does not allow array of variable size in
1796 // WHERE clauses (in the default installation), so we have to choose
1797 // this expensive and somewhat ugly way
1798 // annotation: postgresql shouldn't have chosen an array here, instead they
1799 // should have multiple rows per table
1800 // LEM: to transform an array into several rows, see unnest;
1801 // it is as simple as "SELECT foo, bar, unnest(qux) FROM ..."
1802 // where qux is the column that contains an array.
1803 while( array
[i
] && '}' != array
[i
] )
1807 while( array
[i
] && array
[i
] != '}' && array
[i
] != ',' ) i
++;
1808 row
[3] <<= array
.copy(start
, i
- start
);
1809 vec
.push_back( row
);
1814 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
1815 if( closeable
.is() )
1820 SequenceAnyVector::iterator ii
= vec
.begin();
1821 OUString lastTableOid
;
1822 sal_Int32 index
= 0;
1823 Sequence
< Sequence
< Any
> > ret( vec
.size() );
1825 for( ; ii
!= vec
.end() ; ++ ii
)
1828 Sequence
< Any
> row
= *ii
;
1832 row
[4] >>= tableOid
;
1834 statement
= m_origin
->prepareStatement(
1835 "SELECT att.attname FROM "
1836 "pg_attribute AS att, pg_class AS cl WHERE "
1837 "att.attrelid = ? AND att.attnum = ?" );
1839 parameters
= Reference
< XParameters
>( statement
, UNO_QUERY_THROW
);
1840 parameters
->setString( 1 , tableOid
);
1841 parameters
->setString( 2 , attnum
);
1843 rs
= statement
->executeQuery();
1844 xRow
= Reference
< XRow
>( rs
, UNO_QUERY_THROW
);
1848 row
[3] <<= xRow
->getString( 1 );
1849 if( tableOid
!= lastTableOid
)
1851 lastTableOid
= tableOid
;
1852 row
[4] <<= OUString::number( index
);
1856 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
1857 if( closeable
.is() )
1860 ret
[elements
] = row
;
1863 return new SequenceResultSet(
1864 m_refMutex
, *this, getStatics().primaryKeyNames
, ret
, m_pSettings
->tc
);
1867 // Copied / adapted / simplified from JDBC driver
1868 #define SQL_CASE_KEYRULE " WHEN 'c' THEN " STRINGIFY(KEYRULE_CASCADE) \
1869 " WHEN 'n' THEN " STRINGIFY(KEYRULE_SET_NULL) \
1870 " WHEN 'd' THEN " STRINGIFY(KEYRULE_SET_DEFAULT) \
1871 " WHEN 'r' THEN " STRINGIFY(KEYRULE_RESTRICT) \
1872 " WHEN 'a' THEN " STRINGIFY(KEYRULE_NO_ACTION) \
1875 #define SQL_GET_REFERENCES \
1876 "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) " \
1877 "SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEM, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, " \
1878 " NULL::text AS FKTABLE_CAT, fkn.nspname AS FKTABLE_SCHEM, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, " \
1879 " con.conkeyseq AS KEY_SEQ, " \
1880 " CASE con.confupdtype " \
1882 " END AS UPDATE_RULE, " \
1883 " CASE con.confdeltype " \
1885 " END AS DELETE_RULE, " \
1886 " con.conname AS FK_NAME, pkic.relname AS PK_NAME, " \
1888 " WHEN con.condeferrable AND con.condeferred THEN " STRINGIFY(DEFERRABILITY_INITIALLY_DEFERRED) \
1889 " WHEN con.condeferrable THEN " STRINGIFY(DEFERRABILITY_INITIALLY_IMMEDIATE) \
1890 " ELSE " STRINGIFY(DEFERRABILITY_NONE) \
1891 " END AS DEFERRABILITY " \
1893 " pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, " \
1894 " pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka, " \
1895 " con, pg_catalog.pg_depend dep, pg_catalog.pg_class pkic " \
1896 "WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey AND con.confrelid = pkc.oid " \
1897 " AND fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey AND con.conrelid = fkc.oid " \
1898 " 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 "
1900 #define SQL_GET_REFERENCES_PSCHEMA " AND pkn.nspname = ? "
1901 #define SQL_GET_REFERENCES_PTABLE " AND pkc.relname = ? "
1902 #define SQL_GET_REFERENCES_FSCHEMA " AND fkn.nspname = ? "
1903 #define SQL_GET_REFERENCES_FTABLE " AND fkc.relname = ? "
1904 #define SQL_GET_REFERENCES_ORDER_SOME_PTABLE "ORDER BY fkn.nspname, fkc.relname, conkeyseq"
1905 #define SQL_GET_REFERENCES_ORDER_NO_PTABLE "ORDER BY pkn.nspname, pkc.relname, conkeyseq"
1907 #define SQL_GET_REFERENCES_NONE_NONE_NONE_NONE \
1908 SQL_GET_REFERENCES \
1909 SQL_GET_REFERENCES_ORDER_NO_PTABLE
1911 #define SQL_GET_REFERENCES_SOME_NONE_NONE_NONE \
1912 SQL_GET_REFERENCES \
1913 SQL_GET_REFERENCES_PSCHEMA \
1914 SQL_GET_REFERENCES_ORDER_NO_PTABLE
1916 #define SQL_GET_REFERENCES_NONE_SOME_NONE_NONE \
1917 SQL_GET_REFERENCES \
1918 SQL_GET_REFERENCES_PTABLE \
1919 SQL_GET_REFERENCES_ORDER_SOME_PTABLE
1921 #define SQL_GET_REFERENCES_SOME_SOME_NONE_NONE \
1922 SQL_GET_REFERENCES \
1923 SQL_GET_REFERENCES_PSCHEMA \
1924 SQL_GET_REFERENCES_PTABLE \
1925 SQL_GET_REFERENCES_ORDER_SOME_PTABLE
1927 #define SQL_GET_REFERENCES_NONE_NONE_SOME_NONE \
1928 SQL_GET_REFERENCES \
1929 SQL_GET_REFERENCES_FSCHEMA \
1930 SQL_GET_REFERENCES_ORDER_NO_PTABLE
1932 #define SQL_GET_REFERENCES_NONE_NONE_NONE_SOME \
1933 SQL_GET_REFERENCES \
1934 SQL_GET_REFERENCES_FTABLE \
1935 SQL_GET_REFERENCES_ORDER_NO_PTABLE
1937 #define SQL_GET_REFERENCES_NONE_NONE_SOME_SOME \
1938 SQL_GET_REFERENCES \
1939 SQL_GET_REFERENCES_FSCHEMA \
1940 SQL_GET_REFERENCES_FTABLE \
1941 SQL_GET_REFERENCES_ORDER_NO_PTABLE
1943 #define SQL_GET_REFERENCES_SOME_NONE_SOME_NONE \
1944 SQL_GET_REFERENCES \
1945 SQL_GET_REFERENCES_PSCHEMA \
1946 SQL_GET_REFERENCES_FSCHEMA \
1947 SQL_GET_REFERENCES_ORDER_NO_PTABLE
1949 #define SQL_GET_REFERENCES_SOME_NONE_NONE_SOME \
1950 SQL_GET_REFERENCES \
1951 SQL_GET_REFERENCES_PSCHEMA \
1952 SQL_GET_REFERENCES_FTABLE \
1953 SQL_GET_REFERENCES_ORDER_NO_PTABLE
1955 #define SQL_GET_REFERENCES_SOME_NONE_SOME_SOME \
1956 SQL_GET_REFERENCES \
1957 SQL_GET_REFERENCES_PSCHEMA \
1958 SQL_GET_REFERENCES_FSCHEMA \
1959 SQL_GET_REFERENCES_FTABLE \
1960 SQL_GET_REFERENCES_ORDER_NO_PTABLE
1962 #define SQL_GET_REFERENCES_NONE_SOME_SOME_NONE \
1963 SQL_GET_REFERENCES \
1964 SQL_GET_REFERENCES_PTABLE \
1965 SQL_GET_REFERENCES_FSCHEMA \
1966 SQL_GET_REFERENCES_ORDER_SOME_PTABLE
1968 #define SQL_GET_REFERENCES_NONE_SOME_NONE_SOME \
1969 SQL_GET_REFERENCES \
1970 SQL_GET_REFERENCES_PTABLE \
1971 SQL_GET_REFERENCES_FTABLE \
1972 SQL_GET_REFERENCES_ORDER_SOME_PTABLE
1974 #define SQL_GET_REFERENCES_NONE_SOME_SOME_SOME \
1975 SQL_GET_REFERENCES \
1976 SQL_GET_REFERENCES_PTABLE \
1977 SQL_GET_REFERENCES_FSCHEMA \
1978 SQL_GET_REFERENCES_FTABLE \
1979 SQL_GET_REFERENCES_ORDER_SOME_PTABLE
1981 #define SQL_GET_REFERENCES_SOME_SOME_SOME_NONE \
1982 SQL_GET_REFERENCES \
1983 SQL_GET_REFERENCES_PSCHEMA \
1984 SQL_GET_REFERENCES_PTABLE \
1985 SQL_GET_REFERENCES_FSCHEMA \
1986 SQL_GET_REFERENCES_ORDER_SOME_PTABLE
1988 #define SQL_GET_REFERENCES_SOME_SOME_NONE_SOME \
1989 SQL_GET_REFERENCES \
1990 SQL_GET_REFERENCES_PSCHEMA \
1991 SQL_GET_REFERENCES_PTABLE \
1992 SQL_GET_REFERENCES_FTABLE \
1993 SQL_GET_REFERENCES_ORDER_SOME_PTABLE
1995 #define SQL_GET_REFERENCES_SOME_SOME_SOME_SOME \
1996 SQL_GET_REFERENCES \
1997 SQL_GET_REFERENCES_PSCHEMA \
1998 SQL_GET_REFERENCES_PTABLE \
1999 SQL_GET_REFERENCES_FSCHEMA \
2000 SQL_GET_REFERENCES_FTABLE \
2001 SQL_GET_REFERENCES_ORDER_SOME_PTABLE
2003 void DatabaseMetaData::init_getReferences_stmt ()
2005 m_getReferences_stmt
[0] = m_origin
->prepareStatement(SQL_GET_REFERENCES_NONE_NONE_NONE_NONE
);
2006 m_getReferences_stmt
[1] = m_origin
->prepareStatement(SQL_GET_REFERENCES_SOME_NONE_NONE_NONE
);
2007 m_getReferences_stmt
[2] = m_origin
->prepareStatement(SQL_GET_REFERENCES_NONE_SOME_NONE_NONE
);
2008 m_getReferences_stmt
[3] = m_origin
->prepareStatement(SQL_GET_REFERENCES_SOME_SOME_NONE_NONE
);
2009 m_getReferences_stmt
[4] = m_origin
->prepareStatement(SQL_GET_REFERENCES_NONE_NONE_SOME_NONE
);
2010 m_getReferences_stmt
[5] = m_origin
->prepareStatement(SQL_GET_REFERENCES_SOME_NONE_SOME_NONE
);
2011 m_getReferences_stmt
[6] = m_origin
->prepareStatement(SQL_GET_REFERENCES_NONE_SOME_SOME_NONE
);
2012 m_getReferences_stmt
[7] = m_origin
->prepareStatement(SQL_GET_REFERENCES_SOME_SOME_SOME_NONE
);
2013 m_getReferences_stmt
[8] = m_origin
->prepareStatement(SQL_GET_REFERENCES_NONE_NONE_NONE_SOME
);
2014 m_getReferences_stmt
[9] = m_origin
->prepareStatement(SQL_GET_REFERENCES_SOME_NONE_NONE_SOME
);
2015 m_getReferences_stmt
[10] = m_origin
->prepareStatement(SQL_GET_REFERENCES_NONE_SOME_NONE_SOME
);
2016 m_getReferences_stmt
[11] = m_origin
->prepareStatement(SQL_GET_REFERENCES_SOME_SOME_NONE_SOME
);
2017 m_getReferences_stmt
[12] = m_origin
->prepareStatement(SQL_GET_REFERENCES_NONE_NONE_SOME_SOME
);
2018 m_getReferences_stmt
[13] = m_origin
->prepareStatement(SQL_GET_REFERENCES_SOME_NONE_SOME_SOME
);
2019 m_getReferences_stmt
[14] = m_origin
->prepareStatement(SQL_GET_REFERENCES_NONE_SOME_SOME_SOME
);
2020 m_getReferences_stmt
[15] = m_origin
->prepareStatement(SQL_GET_REFERENCES_SOME_SOME_SOME_SOME
);
2023 void DatabaseMetaData::init_getPrivs_stmt ()
2025 OUStringBuffer
sSQL(300);
2027 " SELECT dp.TABLE_CAT, dp.TABLE_SCHEM, dp.TABLE_NAME, dp.GRANTOR, pr.rolname AS GRANTEE, dp.privilege, dp.is_grantable "
2029 " SELECT table_catalog AS TABLE_CAT, table_schema AS TABLE_SCHEM, table_name,"
2030 " grantor, grantee, privilege_type AS PRIVILEGE, is_grantable"
2031 " FROM information_schema.table_privileges");
2032 if ( PQserverVersion( m_pSettings
->pConnection
) < 90200 )
2033 // information_schema.table_privileges does not fill in default ACLs when no ACL
2034 // assume default ACL is "owner has all privileges" and add it
2037 " SELECT current_database() AS TABLE_CAT, pn.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME,"
2038 " ro.rolname AS GRANTOR, rg.rolname AS GRANTEE, p.privilege, 'YES' AS is_grantable"
2039 " FROM pg_catalog.pg_class c,"
2040 " (VALUES ('SELECT'), ('INSERT'), ('UPDATE'), ('DELETE'), ('TRUNCATE'), ('REFERENCES'), ('TRIGGER')) p (privilege),"
2041 " pg_catalog.pg_roles ro,"
2042 " ( SELECT oid, rolname FROM pg_catalog.pg_roles"
2044 " VALUES (0::oid, 'PUBLIC')"
2045 " ) AS rg (oid, rolname),"
2046 " pg_catalog.pg_namespace pn"
2047 " WHERE c.relkind IN ('r', 'v') AND c.relacl IS NULL AND pg_has_role(rg.oid, c.relowner, 'USAGE')"
2048 " AND c.relowner=ro.oid AND c.relnamespace = pn.oid");
2051 " (SELECT oid, rolname FROM pg_catalog.pg_roles UNION ALL VALUES (0, 'PUBLIC')) pr"
2052 " WHERE table_schem LIKE ? AND table_name LIKE ? AND (dp.grantee = 'PUBLIC' OR pg_has_role(pr.oid, dp.grantee, 'USAGE'))"
2053 " ORDER BY table_schem, table_name, privilege" );
2055 m_getTablePrivs_stmt
= m_origin
->prepareStatement( sSQL
.makeStringAndClear() );
2058 " 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 ("
2059 " SELECT table_catalog AS TABLE_CAT, table_schema AS TABLE_SCHEM, table_name, column_name,"
2060 " grantor, grantee, privilege_type AS PRIVILEGE, is_grantable"
2061 " FROM information_schema.column_privileges");
2062 if ( PQserverVersion( m_pSettings
->pConnection
) < 90200 )
2063 // information_schema.table_privileges does not fill in default ACLs when no ACL
2064 // assume default ACL is "owner has all privileges" and add it
2067 " SELECT current_database() AS TABLE_CAT, pn.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, a.attname AS column_name,"
2068 " ro.rolname AS GRANTOR, rg.rolname AS GRANTEE, p.privilege, 'YES' AS is_grantable"
2069 " FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a,"
2070 " (VALUES ('SELECT'), ('INSERT'), ('UPDATE'), ('REFERENCES')) p (privilege),"
2071 " pg_catalog.pg_roles ro,"
2072 " ( SELECT oid, rolname FROM pg_catalog.pg_roles"
2074 " VALUES (0::oid, 'PUBLIC')"
2075 " ) AS rg (oid, rolname),"
2076 " pg_catalog.pg_namespace pn"
2077 " WHERE c.relkind IN ('r', 'v') AND c.relacl IS NULL AND pg_has_role(rg.oid, c.relowner, 'USAGE')"
2078 " AND c.relowner=ro.oid AND c.relnamespace = pn.oid AND a.attrelid = c.oid AND a.attnum > 0");
2081 " (SELECT oid, rolname FROM pg_catalog.pg_roles UNION ALL VALUES (0, 'PUBLIC')) pr"
2082 " WHERE table_schem = ? AND table_name = ? AND column_name LIKE ? AND (dp.grantee = 'PUBLIC' OR pg_has_role(pr.oid, dp.grantee, 'USAGE'))"
2083 " ORDER BY column_name, privilege" );
2085 m_getColumnPrivs_stmt
= m_origin
->prepareStatement( sSQL
.makeStringAndClear() );
2088 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getImportedExportedKeys(
2089 const Any
& /* primaryCatalog */,
2090 const OUString
& primarySchema
,
2091 const OUString
& primaryTable
,
2092 const Any
& /* foreignCatalog */,
2093 const OUString
& foreignSchema
,
2094 const OUString
& foreignTable
) throw (SQLException
, RuntimeException
)
2097 if ( ! primarySchema
.isEmpty() )
2099 if ( ! primaryTable
.isEmpty() )
2101 if ( ! foreignSchema
.isEmpty() )
2103 if ( ! foreignTable
.isEmpty() )
2106 Reference
< XPreparedStatement
> stmt
= m_getReferences_stmt
[i
];
2107 Reference
< XParameters
> param ( stmt
, UNO_QUERY_THROW
);
2111 param
->setString( j
++, primarySchema
);
2113 param
->setString( j
++, primaryTable
);
2115 param
->setString( j
++, foreignSchema
);
2117 param
->setString( j
++, foreignTable
);
2119 Reference
< XResultSet
> rs
= stmt
->executeQuery();
2125 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getImportedKeys(
2126 const ::com::sun::star::uno::Any
& catalog
,
2127 const OUString
& schema
,
2128 const OUString
& table
) throw (SQLException
, RuntimeException
, std::exception
)
2130 return getImportedExportedKeys(Any(), OUString(), OUString(), catalog
, schema
, table
);
2133 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getExportedKeys(
2134 const ::com::sun::star::uno::Any
& catalog
,
2135 const OUString
& schema
,
2136 const OUString
& table
) throw (SQLException
, RuntimeException
, std::exception
)
2138 return getImportedExportedKeys(catalog
, schema
, table
, Any(), OUString(), OUString());
2141 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getCrossReference(
2142 const ::com::sun::star::uno::Any
& primaryCatalog
,
2143 const OUString
& primarySchema
,
2144 const OUString
& primaryTable
,
2145 const ::com::sun::star::uno::Any
& foreignCatalog
,
2146 const OUString
& foreignSchema
,
2147 const OUString
& foreignTable
) throw (SQLException
, RuntimeException
, std::exception
)
2149 return getImportedExportedKeys( primaryCatalog
, primarySchema
, primaryTable
, foreignCatalog
, foreignSchema
, foreignTable
);
2153 struct TypeInfoByDataTypeSorter
2155 bool operator () ( const Sequence
< Any
> & a
, const Sequence
< Any
> & b
)
2159 a
[1 /*DATA_TYPE*/] >>= valueA
;
2160 b
[1 /*DATA_TYPE*/] >>= valueB
;
2161 if( valueB
.toInt32() == valueA
.toInt32() )
2165 a
[0 /*TYPE_NAME*/] >>= nameA
;
2166 b
[0 /*TYPE_NAME*/] >>= nameB
;
2167 if( nameA
.startsWith( "int4" ) )
2169 if( nameB
.startsWith( "int4" ) )
2171 return nameA
.compareTo( nameB
) < 0;
2174 return valueA
.toInt32() < valueB
.toInt32();
2175 // sal_Int32 valueA;
2176 // sal_Int32 valueB;
2177 // a[1 /*DATA_TYPE*/] >>= valueA;
2178 // b[1 /*DATA_TYPE*/] >>= valueB;
2179 // if( valueB == valueA )
2183 // a[0 /*TYPE_NAME*/] >>= nameA;
2184 // b[0 /*TYPE_NAME*/] >>= nameB;
2185 // return nameA.compareTo( nameB ) < 0;
2188 // return valueA < valueB;
2192 static sal_Int32
calcSearchable( sal_Int32 dataType
)
2194 sal_Int32 ret
= com::sun::star::sdbc::ColumnSearch::FULL
;
2195 if( com::sun::star::sdbc::DataType::BINARY
== dataType
||
2196 com::sun::star::sdbc::DataType::VARBINARY
== dataType
||
2197 com::sun::star::sdbc::DataType::LONGVARBINARY
== dataType
)
2198 ret
= com::sun::star::sdbc::ColumnSearch::NONE
;
2203 static sal_Int32
getMaxScale( sal_Int32 dataType
)
2205 // LEM TODO: review, see where used, see JDBC, ...
2207 if( dataType
== com::sun::star::sdbc::DataType::NUMERIC
)
2208 ret
= 1000; // see pg-docs DataType/numeric
2209 // else if( dataType == DataType::DOUBLE )
2211 // else if( dataType == DataType::FLOAT )
2219 const char * typeName
;
2220 const char * createParam
;
2222 sal_Int32 precision
;
2225 sal_Int32 searchable
;
2228 static void pgTypeInfo2ResultSet(
2229 SequenceAnyVector
&vec
,
2230 const Reference
< XResultSet
> &rs
)
2232 static const sal_Int32 TYPE_NAME
= 0; // string Type name
2233 static const sal_Int32 DATA_TYPE
= 1; // short SQL data type from java.sql.Types
2234 static const sal_Int32 PRECISION
= 2; // long maximum precision
2235 static const sal_Int32 CREATE_PARAMS
= 5; // string => parameters used in creating the type (may be NULL )
2236 static const sal_Int32 NULLABLE
= 6; // short ==> can you use NULL for this type?
2237 // - NO_NULLS - does not allow NULL values
2238 // - NULLABLE - allows NULL values
2239 // - NULLABLE_UNKNOWN - nullability unknown
2241 static const sal_Int32 CASE_SENSITIVE
= 7; // boolean==> is it case sensitive
2242 static const sal_Int32 SEARCHABLE
= 8; // short ==>; can you use
2243 // "WHERE" based on this type:
2244 // - NONE - No support
2245 // - CHAR - Only supported with WHERE .. LIKE
2246 // - BASIC - Supported except for WHERE .. LIKE
2247 // - FULL - Supported for all WHERE ..
2248 static const sal_Int32 UNSIGNED_ATTRIBUTE
= 9; // boolean ==> is it unsigned?
2249 static const sal_Int32 FIXED_PREC_SCALE
= 10; // boolean ==> can it be a money value?
2250 static const sal_Int32 AUTO_INCREMENT
= 11; // boolean ==> can it be used for
2251 // an auto-increment value?
2252 static const sal_Int32 MINIMUM_SCALE
= 13; // short ==> minimum scale supported
2253 static const sal_Int32 MAXIMUM_SCALE
= 14; // short ==> maximum scale supported
2254 static const sal_Int32 NUM_PREC_RADIX
= 17; // long ==> usually 2 or 10
2256 /* not filled so far
2257 3. LITERAL_PREFIX string ==> prefix used to quote a literal
2259 4, LITERAL_SUFFIX string ==> suffix used to quote a literal
2261 5. CREATE_PARAMS string ==> parameters used in creating thw type (may be <NULL/>)
2262 12. LOCAL_TYPE_NAME string ==> localized version of type name (may be <NULL/>)
2263 15, SQL_DATA_TYPE long ==> unused
2264 16. SQL_DATETIME_SUB long ==> unused
2266 Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
2269 Sequence
< Any
> row(18);
2271 sal_Int32 dataType
=typeNameToDataType(xRow
->getString(5),xRow
->getString(2));
2272 sal_Int32 precision
= xRow
->getString(3).toInt32();
2274 if( dataType
== com::sun::star::sdbc::DataType::CHAR
||
2275 ( dataType
== com::sun::star::sdbc::DataType::VARCHAR
&&
2276 xRow
->getString(TYPE_NAME
+1).equalsIgnoreAsciiCase("varchar") ) )
2278 // reflect varchar as varchar with upper limit !
2279 //NOTE: the sql spec requires varchar to have an upper limit, however
2280 // in postgresql the upper limit is optional, no limit means unlimited
2282 precision
= 0x40000000; // about 1 GB, see character type docs in postgresql
2283 row
[CREATE_PARAMS
] <<= OUString("length");
2285 else if( dataType
== com::sun::star::sdbc::DataType::NUMERIC
)
2288 row
[CREATE_PARAMS
] <<= OUString("length, scale");
2291 row
[TYPE_NAME
] <<= xRow
->getString(1);
2292 row
[DATA_TYPE
] <<= OUString::number(dataType
);
2293 row
[PRECISION
] <<= OUString::number( precision
);
2294 sal_Int32 nullable
= xRow
->getBoolean(4) ?
2295 com::sun::star::sdbc::ColumnValue::NO_NULLS
:
2296 com::sun::star::sdbc::ColumnValue::NULLABLE
;
2297 row
[NULLABLE
] <<= OUString::number(nullable
);
2298 row
[CASE_SENSITIVE
] <<= OUString::number(1);
2299 row
[SEARCHABLE
] <<= OUString::number( calcSearchable( dataType
) );
2300 row
[UNSIGNED_ATTRIBUTE
] <<= OUString("0");
2301 if( com::sun::star::sdbc::DataType::INTEGER
== dataType
||
2302 com::sun::star::sdbc::DataType::BIGINT
== dataType
)
2303 row
[AUTO_INCREMENT
] <<= OUString("1"); // TODO
2305 row
[AUTO_INCREMENT
] <<= OUString("0"); // TODO
2306 row
[MINIMUM_SCALE
] <<= OUString("0"); // TODO: what is this ?
2307 row
[MAXIMUM_SCALE
] <<= OUString::number( getMaxScale( dataType
) );
2308 row
[NUM_PREC_RADIX
] <<= OUString("10"); // TODO: what is this ?
2309 (void)FIXED_PREC_SCALE
;
2310 vec
.push_back( row
);
2316 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getTypeInfo( )
2317 throw (SQLException
, RuntimeException
, std::exception
)
2319 // Note: Indexes start at 0 (in the API doc, they start at 1)
2320 MutexGuard
guard( m_refMutex
->mutex
);
2323 if( isLog( m_pSettings
, LogLevel::INFO
) )
2325 log( m_pSettings
, LogLevel::INFO
, "DatabaseMetaData::getTypeInfo() got called" );
2328 Reference
< XStatement
> statement
= m_origin
->createStatement();
2329 Reference
< XResultSet
> rs
= statement
->executeQuery(
2330 "SELECT pg_type.typname AS typname," //1
2331 "pg_type.typtype AS typtype," //2
2332 "pg_type.typlen AS typlen," //3
2333 "pg_type.typnotnull AS typnotnull," //4
2334 "pg_type.typname AS typname " //5
2336 "WHERE pg_type.typtype = 'b' "
2337 "OR pg_type.typtype = 'p'"
2340 SequenceAnyVector vec
;
2341 pgTypeInfo2ResultSet( vec
, rs
);
2343 // check for domain types
2344 rs
= statement
->executeQuery(
2345 "SELECT t1.typname as typname,"
2346 "t2.typtype AS typtype,"
2347 "t2.typlen AS typlen,"
2348 "t2.typnotnull AS typnotnull,"
2349 "t2.typname as realtypname "
2350 "FROM pg_type as t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype=t2.oid "
2351 "WHERE t1.typtype = 'd'" );
2352 pgTypeInfo2ResultSet( vec
, rs
);
2354 std::sort( vec
.begin(), vec
.end(), TypeInfoByDataTypeSorter() );
2356 return new SequenceResultSet(
2359 getStatics().typeinfoColumnNames
,
2360 sequence_of_vector(vec
),
2362 &( getStatics().typeInfoMetaData
));
2366 static sal_Int32
seqContains( const Sequence
< sal_Int32
> &seq
, sal_Int32 value
)
2369 for( int i
= 0; i
< seq
.getLength(); i
++ )
2371 if( seq
[i
] == value
)
2380 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getIndexInfo(
2381 const ::com::sun::star::uno::Any
& catalog
,
2382 const OUString
& schema
,
2383 const OUString
& table
,
2385 sal_Bool approximate
) throw (SQLException
, RuntimeException
, std::exception
)
2387 (void) catalog
; (void) approximate
;
2389 MutexGuard
guard( m_refMutex
->mutex
);
2393 1. TABLE_CAT string -> table catalog (may be NULL )
2394 2. TABLE_SCHEM string -> table schema (may be NULL )
2395 3. TABLE_NAME string -> table name
2396 4. NON_UNIQUE boolean -> Can index values be non-unique?
2397 false when TYPE is tableIndexStatistic
2398 5. INDEX_QUALIFIER string -> index catalog (may be NULL );
2399 NULL when TYPE is tableIndexStatistic
2400 6. INDEX_NAME string -> index name; NULL when TYPE is tableIndexStatistic
2401 7. TYPE short -> index type:
2402 * 0 - this identifies table statistics that are returned
2403 in conjuction with a table's index descriptions
2404 * CLUSTERED - this is a clustered index
2405 * HASHED - this is a hashed index
2406 * OTHER - this is some other style of index
2407 8. ORDINAL_POSITION short -> column sequence number within index;
2408 zero when TYPE is tableIndexStatistic
2409 9. COLUMN_NAME string -> column name; NULL when TYPE is tableIndexStatistic
2410 10. ASC_OR_DESC string -> column sort sequence, "A"= ascending,
2411 "D" = descending, may be NULL if sort sequence
2412 is not supported; NULL when TYPE is tableIndexStatistic
2413 11. CARDINALITY long -> When TYPE is tableIndexStatistic, then this is
2414 the number of rows in the table; otherwise, it
2415 is the number of unique values in the index.
2416 12. PAGES long -> When TYPE is tableIndexStatisic then this is
2417 the number of pages used for the table, otherwise
2418 it is the number of pages used for the current index.
2419 13. FILTER_CONDITION string -> Filter condition, if any. (may be NULL )
2422 static const sal_Int32 C_SCHEMA
= 1;
2423 static const sal_Int32 C_TABLENAME
= 2;
2424 static const sal_Int32 C_INDEXNAME
= 3;
2425 static const sal_Int32 C_IS_CLUSTERED
= 4;
2426 static const sal_Int32 C_IS_UNIQUE
= 5;
2427 static const sal_Int32 C_IS_PRIMARY
= 6;
2428 static const sal_Int32 C_COLUMNS
= 7;
2430 static const sal_Int32 R_TABLE_SCHEM
= 1;
2431 static const sal_Int32 R_TABLE_NAME
= 2;
2432 static const sal_Int32 R_NON_UNIQUE
= 3;
2433 static const sal_Int32 R_INDEX_NAME
= 5;
2434 static const sal_Int32 R_TYPE
= 6;
2435 static const sal_Int32 R_ORDINAL_POSITION
= 7;
2436 static const sal_Int32 R_COLUMN_NAME
= 8;
2438 Reference
< XPreparedStatement
> stmt
= m_origin
->prepareStatement(
2439 "SELECT nspname, " // 1
2440 "pg_class.relname, " // 2
2441 "class2.relname, " // 3
2442 "indisclustered, " // 4
2443 "indisunique, " // 5
2444 "indisprimary, " // 6
2446 "FROM pg_index INNER JOIN pg_class ON indrelid = pg_class.oid "
2447 "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
2448 "INNER JOIN pg_class as class2 ON pg_index.indexrelid = class2.oid "
2449 "WHERE nspname = ? AND pg_class.relname = ?" );
2451 Reference
< XParameters
> param ( stmt
, UNO_QUERY_THROW
);
2452 param
->setString( 1, schema
);
2453 param
->setString( 2, table
);
2454 Reference
< XResultSet
> rs
= stmt
->executeQuery();
2455 Reference
< XRow
> xRow ( rs
, UNO_QUERY_THROW
);
2457 SequenceAnyVector vec
;
2460 Sequence
< sal_Int32
> columns
= parseIntArray( xRow
->getString(C_COLUMNS
) );
2461 Reference
< XPreparedStatement
> columnsStmt
= m_origin
->prepareStatement(
2462 "SELECT attnum, attname "
2463 "FROM pg_attribute "
2464 " INNER JOIN pg_class ON attrelid = pg_class.oid "
2465 " INNER JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid "
2466 " WHERE pg_namespace.nspname=? AND pg_class.relname=?" );
2467 Reference
< XParameters
> paramColumn ( columnsStmt
, UNO_QUERY_THROW
);
2468 OUString currentSchema
= xRow
->getString( C_SCHEMA
);
2469 OUString currentTable
= xRow
->getString( C_TABLENAME
);
2470 OUString currentIndexName
= xRow
->getString( C_INDEXNAME
);
2471 sal_Bool isNonUnique
= ! xRow
->getBoolean( C_IS_UNIQUE
);
2472 bool isPrimary
= xRow
->getBoolean( C_IS_PRIMARY
);
2474 sal_Int32 indexType
= xRow
->getBoolean( C_IS_CLUSTERED
) ?
2475 com::sun::star::sdbc::IndexType::CLUSTERED
:
2476 com::sun::star::sdbc::IndexType::HASHED
;
2478 paramColumn
->setString( C_SCHEMA
, currentSchema
);
2479 paramColumn
->setString( C_TABLENAME
, currentTable
);
2481 Reference
< XResultSet
> rsColumn
= columnsStmt
->executeQuery();
2482 Reference
< XRow
> rowColumn( rsColumn
, UNO_QUERY_THROW
);
2483 while( rsColumn
->next() )
2485 sal_Int32 pos
= seqContains( columns
, rowColumn
->getInt( 1 ) );
2486 if( pos
>= 0 && ( ! isNonUnique
|| ! unique
) )
2488 Sequence
< Any
> result( 13 );
2489 result
[R_TABLE_SCHEM
] = makeAny(currentSchema
);
2490 result
[R_TABLE_NAME
] = makeAny(currentTable
);
2491 result
[R_INDEX_NAME
] = makeAny(currentIndexName
);
2492 result
[R_NON_UNIQUE
] =
2493 Any( &isNonUnique
, getBooleanCppuType() );
2494 result
[R_TYPE
] = makeAny( indexType
);
2495 result
[R_COLUMN_NAME
] = makeAny( rowColumn
->getString(2) );
2496 sal_Int32 nPos
= ((sal_Int32
)pos
+1); // MSVC++ nonsense
2497 result
[R_ORDINAL_POSITION
] = makeAny( nPos
);
2498 vec
.push_back( result
);
2502 return new SequenceResultSet(
2503 m_refMutex
, *this, getStatics().indexinfoColumnNames
,
2504 sequence_of_vector(vec
),
2508 sal_Bool
DatabaseMetaData::supportsResultSetType( sal_Int32 setType
)
2509 throw (SQLException
, RuntimeException
, std::exception
)
2511 if ( setType
== com::sun::star::sdbc::ResultSetType::SCROLL_SENSITIVE
)
2517 sal_Bool
DatabaseMetaData::supportsResultSetConcurrency(
2518 sal_Int32 setType
, sal_Int32 concurrency
) throw (SQLException
, RuntimeException
, std::exception
)
2521 if ( ! supportsResultSetType( setType
) )
2527 sal_Bool
DatabaseMetaData::ownUpdatesAreVisible( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2532 sal_Bool
DatabaseMetaData::ownDeletesAreVisible( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2537 sal_Bool
DatabaseMetaData::ownInsertsAreVisible( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2542 sal_Bool
DatabaseMetaData::othersUpdatesAreVisible( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2547 sal_Bool
DatabaseMetaData::othersDeletesAreVisible( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2552 sal_Bool
DatabaseMetaData::othersInsertsAreVisible( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2557 sal_Bool
DatabaseMetaData::updatesAreDetected( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2562 sal_Bool
DatabaseMetaData::deletesAreDetected( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2566 sal_Bool
DatabaseMetaData::insertsAreDetected( sal_Int32
/* setType */ ) throw (SQLException
, RuntimeException
, std::exception
)
2571 sal_Bool
DatabaseMetaData::supportsBatchUpdates( ) throw (SQLException
, RuntimeException
, std::exception
)
2576 ::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
, std::exception
)
2578 (void) catalog
; (void) schemaPattern
; (void) typeNamePattern
; (void) types
;
2579 //LEM TODO: implement! See JDBC driver
2580 MutexGuard
guard( m_refMutex
->mutex
);
2582 return new SequenceResultSet(
2583 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
2586 ::com::sun::star::uno::Reference
< com::sun::star::sdbc::XConnection
> DatabaseMetaData::getConnection()
2587 throw (SQLException
, RuntimeException
, std::exception
)
2593 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */