clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pq_xtables.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D PQ_SDBC_MAJOR=0 -D PQ_SDBC_MINOR=8 -D PQ_SDBC_MICRO=2 -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/openldap/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/postgresql/src/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/postgresql/src/interfaces/libpq -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/nss/dist/public/nss -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/nss/dist/out/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/connectivity/source/drivers/postgresql/pq_xtables.cxx
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | #include <rtl/ustrbuf.hxx> |
38 | #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> |
39 | #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> |
40 | #include <com/sun/star/sdbc/SQLException.hpp> |
41 | #include <com/sun/star/sdbc/XRow.hpp> |
42 | #include <com/sun/star/sdbcx/Privilege.hpp> |
43 | #include <com/sun/star/sdbc/DataType.hpp> |
44 | #include <cppuhelper/exc_hlp.hxx> |
45 | |
46 | #include "pq_xtables.hxx" |
47 | #include "pq_xviews.hxx" |
48 | #include "pq_xtable.hxx" |
49 | #include "pq_statics.hxx" |
50 | #include "pq_tools.hxx" |
51 | |
52 | using osl::MutexGuard; |
53 | |
54 | using com::sun::star::beans::XPropertySet; |
55 | |
56 | using com::sun::star::uno::Any; |
57 | using com::sun::star::uno::makeAny; |
58 | using com::sun::star::uno::UNO_QUERY; |
59 | using com::sun::star::uno::Reference; |
60 | using com::sun::star::uno::Sequence; |
61 | |
62 | using com::sun::star::container::XEnumerationAccess; |
63 | using com::sun::star::container::XEnumeration; |
64 | |
65 | using com::sun::star::sdbc::XRow; |
66 | using com::sun::star::sdbc::XStatement; |
67 | using com::sun::star::sdbc::XResultSet; |
68 | using com::sun::star::sdbc::XDatabaseMetaData; |
69 | using com::sun::star::sdbcx::XColumnsSupplier; |
70 | using com::sun::star::sdbcx::XKeysSupplier; |
71 | |
72 | namespace pq_sdbc_driver |
73 | { |
74 | Tables::Tables( |
75 | const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex, |
76 | const css::uno::Reference< css::sdbc::XConnection > & origin, |
77 | ConnectionSettings *pSettings ) |
78 | : Container( refMutex, origin, pSettings, getStatics().TABLE ) |
79 | {} |
80 | |
81 | Tables::~Tables() |
82 | {} |
83 | |
84 | void Tables::refresh() |
85 | { |
86 | try |
87 | { |
88 | osl::MutexGuard guard( m_xMutex->GetMutex() ); |
89 | Statics & st = getStatics(); |
90 | |
91 | Reference< XDatabaseMetaData > meta = m_origin->getMetaData(); |
92 | |
93 | Reference< XResultSet > rs = |
94 | meta->getTables( Any(), st.cPERCENT,st.cPERCENT, Sequence< OUString > () ); |
95 | |
96 | Reference< XRow > xRow( rs , UNO_QUERY ); |
97 | |
98 | String2IntMap map; |
99 | |
100 | m_values.clear(); |
101 | sal_Int32 tableIndex = 0; |
102 | while( rs->next() ) |
103 | { |
104 | |
105 | |
106 | Table * pTable = |
107 | new Table( m_xMutex, m_origin, m_pSettings ); |
108 | Reference< css::beans::XPropertySet > prop = pTable; |
109 | |
110 | OUString name = xRow->getString( TABLE_INDEX_NAME+1); |
111 | OUString schema = xRow->getString( TABLE_INDEX_SCHEMA+1); |
112 | pTable->setPropertyValue_NoBroadcast_public( |
113 | st.CATALOG_NAME , makeAny(xRow->getString( TABLE_INDEX_CATALOG+1) ) ); |
114 | pTable->setPropertyValue_NoBroadcast_public( st.NAME , makeAny( name ) ); |
115 | pTable->setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME , makeAny( schema )); |
116 | pTable->setPropertyValue_NoBroadcast_public( |
117 | st.TYPE , makeAny( xRow->getString( TABLE_INDEX_TYPE+1) ) ); |
118 | pTable->setPropertyValue_NoBroadcast_public( |
119 | st.DESCRIPTION , makeAny( xRow->getString( TABLE_INDEX_REMARKS+1) ) ); |
120 | pTable->setPropertyValue_NoBroadcast_public( |
121 | st.PRIVILEGES , |
122 | makeAny( sal_Int32( css::sdbcx::Privilege::SELECT | |
123 | css::sdbcx::Privilege::INSERT | |
124 | css::sdbcx::Privilege::UPDATE | |
125 | css::sdbcx::Privilege::DELETE | |
126 | css::sdbcx::Privilege::READ | |
127 | css::sdbcx::Privilege::CREATE | |
128 | css::sdbcx::Privilege::ALTER | |
129 | css::sdbcx::Privilege::REFERENCE | |
130 | css::sdbcx::Privilege::DROP ) ) ); |
131 | |
132 | { |
133 | m_values.push_back( makeAny( prop ) ); |
134 | map[ schema + "." + name ] = tableIndex; |
135 | ++tableIndex; |
136 | } |
137 | } |
138 | m_name2index.swap( map ); |
139 | } |
140 | catch ( const css::sdbc::SQLException & e ) |
141 | { |
142 | css::uno::Any anyEx = cppu::getCaughtException(); |
143 | throw css::lang::WrappedTargetRuntimeException( e.Message, |
144 | e.Context, anyEx ); |
145 | } |
146 | |
147 | fire( RefreshedBroadcaster( *this ) ); |
148 | } |
149 | |
150 | |
151 | static void appendColumnList( |
152 | OUStringBuffer &buf, const Reference< XColumnsSupplier > & columnSupplier, ConnectionSettings *settings ) |
153 | { |
154 | if( !columnSupplier.is() ) |
155 | return; |
156 | |
157 | Reference< XEnumerationAccess > columns( columnSupplier->getColumns(),UNO_QUERY ); |
158 | if( !columns.is() ) |
159 | return; |
160 | |
161 | Reference< XEnumeration > xEnum( columns->createEnumeration() ); |
162 | bool first = true; |
163 | Statics & st = getStatics(); |
164 | |
165 | while( xEnum.is() && xEnum->hasMoreElements() ) |
166 | { |
167 | if( first ) |
168 | { |
169 | first = false; |
170 | } |
171 | else |
172 | { |
173 | buf.append( ", " ); |
174 | } |
175 | Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY ); |
176 | OUString name = extractStringProperty( column, st.NAME ); |
177 | OUString defaultValue = extractStringProperty( column, st.DEFAULT_VALUE ); |
178 | bool isNullable = extractBoolProperty( column, st.IS_NULLABLE ); |
179 | bool isAutoIncrement = extractBoolProperty( column, st.IS_AUTO_INCREMENT ); |
180 | |
181 | bufferQuoteIdentifier( buf, name, settings ); |
182 | |
183 | OUString type = sqltype2string( column ); |
184 | if( isAutoIncrement ) |
185 | { |
186 | sal_Int32 dataType = 0; |
187 | column->getPropertyValue( st.TYPE ) >>= dataType; |
188 | if( css::sdbc::DataType::INTEGER == dataType ) |
189 | { |
190 | buf.append( " serial "); |
191 | isNullable = false; |
192 | } |
193 | else if( css::sdbc::DataType::BIGINT == dataType ) |
194 | { |
195 | buf.append( " serial8 " ); |
196 | isNullable = false; |
197 | } |
198 | else |
199 | buf.append( type ); |
200 | } |
201 | else |
202 | { |
203 | buf.append( type ); |
204 | } |
205 | if( !defaultValue.isEmpty() ) |
206 | { |
207 | bufferQuoteConstant( buf, defaultValue, settings ); |
208 | } |
209 | |
210 | if( ! isNullable ) |
211 | buf.append( " NOT NULL " ); |
212 | |
213 | } |
214 | } |
215 | |
216 | static void appendKeyList( |
217 | OUStringBuffer & buf, const Reference< XKeysSupplier > &keySupplier, ConnectionSettings *settings ) |
218 | { |
219 | if( !keySupplier.is() ) |
220 | return; |
221 | |
222 | Reference< XEnumerationAccess > keys( keySupplier->getKeys(), UNO_QUERY ); |
223 | if(keys.is() ) |
224 | { |
225 | Reference< XEnumeration > xEnum = keys->createEnumeration(); |
226 | while( xEnum.is() && xEnum->hasMoreElements() ) |
227 | { |
228 | buf.append( ", " ); |
229 | Reference< XPropertySet > key( xEnum->nextElement(), UNO_QUERY ); |
230 | bufferKey2TableConstraint( buf, key, settings ); |
231 | } |
232 | } |
233 | } |
234 | |
235 | void Tables::appendByDescriptor( |
236 | const css::uno::Reference< css::beans::XPropertySet >& descriptor ) |
237 | { |
238 | osl::MutexGuard guard( m_xMutex->GetMutex() ); |
239 | Reference< XStatement > stmt = |
240 | m_origin->createStatement(); |
241 | |
242 | Statics &st = getStatics(); |
243 | OUString name,schema; |
244 | descriptor->getPropertyValue( st.SCHEMA_NAME ) >>= schema; |
245 | descriptor->getPropertyValue( st.NAME ) >>= name; |
246 | |
247 | TransactionGuard transaction( stmt ); |
248 | |
249 | OUStringBuffer buf( 128 ); |
250 | buf.append( "CREATE TABLE" ); |
251 | bufferQuoteQualifiedIdentifier( buf, schema, name , m_pSettings); |
252 | buf.append( "(" ); |
253 | |
254 | |
255 | Reference< XColumnsSupplier > supplier( descriptor, UNO_QUERY ); |
256 | appendColumnList( buf, supplier, m_pSettings ); |
257 | |
258 | appendKeyList( buf, Reference< XKeysSupplier >( descriptor, UNO_QUERY ), m_pSettings ); |
259 | |
260 | buf.append( ") " ); |
261 | |
262 | transaction.executeUpdate( buf.makeStringAndClear() ); |
263 | |
264 | |
265 | OUString description = extractStringProperty( descriptor, st.DESCRIPTION ); |
266 | if( !description.isEmpty() ) |
267 | { |
268 | buf.truncate(); |
269 | buf.append( "COMMENT ON TABLE" ); |
270 | bufferQuoteQualifiedIdentifier( buf, schema, name, m_pSettings ); |
271 | buf.append( "IS " ); |
272 | bufferQuoteConstant( buf, description, m_pSettings); |
273 | |
274 | transaction.executeUpdate( buf.makeStringAndClear() ); |
275 | } |
276 | |
277 | |
278 | if( supplier.is() ) |
279 | { |
280 | Reference< XEnumerationAccess > columns( supplier->getColumns(),UNO_QUERY ); |
281 | if( columns.is() ) |
282 | { |
283 | Reference< XEnumeration > xEnum( columns->createEnumeration() ); |
284 | while( xEnum.is() && xEnum->hasMoreElements() ) |
285 | { |
286 | Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY ); |
287 | description = extractStringProperty( column,st.DESCRIPTION ); |
288 | if( !description.isEmpty() ) |
289 | { |
290 | buf.truncate(); |
291 | buf.append( "COMMENT ON COLUMN " ); |
292 | bufferQuoteQualifiedIdentifier( |
293 | buf, schema, name, extractStringProperty( column, st.NAME ), m_pSettings ); |
294 | buf.append( "IS " ); |
295 | bufferQuoteConstant( buf, description, m_pSettings ); |
296 | transaction.executeUpdate( buf.makeStringAndClear() ); |
297 | } |
298 | } |
299 | } |
300 | } |
301 | |
302 | transaction.commit(); |
303 | |
304 | disposeNoThrow( stmt ); |
305 | |
306 | |
307 | refresh(); |
308 | } |
309 | |
310 | void Tables::dropByIndex( sal_Int32 index ) |
311 | { |
312 | osl::MutexGuard guard( m_xMutex->GetMutex() ); |
313 | if( index < 0 || index >= static_cast<sal_Int32>(m_values.size()) ) |
314 | { |
315 | throw css::lang::IndexOutOfBoundsException( |
316 | "TABLES: Index out of range (allowed 0 to " + OUString::number(m_values.size() -1) |
317 | + ", got " + OUString::number( index ) + ")", |
318 | *this ); |
319 | } |
320 | |
321 | Reference< XPropertySet > set; |
322 | m_values[index] >>= set; |
323 | Statics &st = getStatics(); |
324 | OUString name,schema; |
325 | set->getPropertyValue( st.SCHEMA_NAME ) >>= schema; |
326 | set->getPropertyValue( st.NAME ) >>= name; |
327 | if( extractStringProperty( set, st.TYPE ) == st.VIEW && m_pSettings->views.is() ) |
328 | { |
329 | m_pSettings->pViewsImpl->dropByName( concatQualified( schema, name ) ); |
330 | } |
331 | else |
332 | { |
333 | OUStringBuffer update( 128 ); |
334 | update.append( "DROP " ); |
335 | if( extractStringProperty( set, st.TYPE ) == st.VIEW ) |
336 | update.append( "VIEW " ); |
337 | else |
338 | update.append( "TABLE " ); |
339 | bufferQuoteQualifiedIdentifier( update, schema, name, m_pSettings ); |
340 | Reference< XStatement > stmt = m_origin->createStatement( ); |
341 | DisposeGuard dispGuard( stmt ); |
342 | stmt->executeUpdate( update.makeStringAndClear() ); |
343 | } |
344 | |
345 | Container::dropByIndex( index ); |
346 | } |
347 | |
348 | |
349 | css::uno::Reference< css::beans::XPropertySet > Tables::createDataDescriptor() |
350 | { |
351 | return new TableDescriptor( m_xMutex, m_origin, m_pSettings ); |
352 | } |
353 | |
354 | Reference< css::container::XNameAccess > Tables::create( |
355 | const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex, |
356 | const css::uno::Reference< css::sdbc::XConnection > & origin, |
357 | ConnectionSettings *pSettings, |
358 | Tables **ppTables) |
359 | { |
360 | *ppTables = new Tables( refMutex, origin, pSettings ); |
| |
361 | Reference< css::container::XNameAccess > ret = *ppTables; |
362 | (*ppTables)->refresh(); |
| 2 | | Called C++ object pointer is null |
|
363 | |
364 | return ret; |
365 | } |
366 | |
367 | }; |
368 | |
369 | |