PGNP Manual
PGNP Manual
PGNP Manual
1 Introduction .................................................................................................................................................................... 6
2 Installation and Product Activation ................................................................................................................................ 7
2.1.1 UI based installation........................................................................................................................................ 7
2.1.2 Determining the installed version of the PGNP provider ............................................................................. 10
2.1.3 Unattended/silent installation ...................................................................................................................... 10
2.1.4 Activation on a computer behind a firewall (in DMZ)................................................................................... 10
3 Provider’s Features ....................................................................................................................................................... 11
3.1 Database Transformation ..................................................................................................................................... 11
3.1.1 Transforming MS SQL 2000 database into a PostgreSQL database using DTSWizard .................................. 11
3.1.2 Transforming MS SQL 2005, 2008, 2012 database into a PostgreSQL database using DTSWizard .............. 14
3.2 Transactions .......................................................................................................................................................... 14
3.2.1 Local Transactions ......................................................................................................................................... 14
3.2.2 Distributed Transactions ............................................................................................................................... 16
3.2.3 PostgreSQL Nested Transactions .................................................................................................................. 17
3.3 Linked Servers ....................................................................................................................................................... 18
3.3.1 Create Linked Server using SQL Server Wizard ............................................................................................. 18
3.3.2 Create Linked Server using SQL Server Stored Procedures .......................................................................... 20
3.3.3 Viewing and changing Linked Server RPC status........................................................................................... 21
3.3.4 Running Linked Server in a separate process (out-of-proc).......................................................................... 21
3.4 Replication with SQL Server 2000 ......................................................................................................................... 22
3.4.1 Configuring Publisher, Subscribers and Distributor ...................................................................................... 22
3.4.2 Creating publication ...................................................................................................................................... 23
3.4.3 Create Snapshot ............................................................................................................................................ 26
3.4.4 Adding Subscribers ........................................................................................................................................ 27
3.4.5 Synchronize ................................................................................................................................................... 31
3.5 Replication with SQL Server 2005/2008/2012 ...................................................................................................... 33
3.5.1 Configure SQL Server as Distributor.............................................................................................................. 33
3.5.2 Configure the publisher to use a specified distribution database ................................................................ 33
3.5.3 Create Linked Server ..................................................................................................................................... 33
3.5.4 Create the snapshot publication ................................................................................................................... 34
3.5.5 Create the snapshot subscription ................................................................................................................. 34
3.5.6 Deleting subscription and publication .......................................................................................................... 36
Page 3
3.5.7 Create publication for transactional replication ........................................................................................... 36
3.5.8 Create subscription for transactional replication ......................................................................................... 37
3.6 Generating reports in SQL Server Reporting Services........................................................................................... 39
3.7 Two phase commit protocol (2PC)........................................................................................................................ 41
3.7.1 Configuring DTC ............................................................................................................................................ 41
3.7.2 Starting DTC Service ...................................................................................................................................... 41
3.7.3 Enabling prepared transactions in PostgreSQL ............................................................................................. 41
3.7.4 Troubleshooting issues with 2PC .................................................................................................................. 41
3.8 FastLoad feature ................................................................................................................................................... 42
3.8.1 Configuring OLE DB connection in BIDS ........................................................................................................ 42
3.8.2 Configuring Source and Destination ............................................................................................................. 43
3.9 The Query Optimizer ............................................................................................................................................. 44
3.9.1 Simple query substitution ............................................................................................................................. 45
3.9.2 Template based substitution ........................................................................................................................ 46
3.9.3 Exact Match scenario: optimizing ROLAP cube ............................................................................................. 47
3.9.4 Optimizing metadata retrieval ...................................................................................................................... 48
3.10 “Hinting” statements ............................................................................................................................................ 50
3.10.1 Copying table from SQL Server to Postgres in DTSWizard ............................................................................ 50
3.10.2 Tweaking Data Flow in SSIS Package............................................................................................................. 51
3.10.3 Using comments to change Extended Properties parameters per statement ............................................. 52
4 Programming with the Provider.................................................................................................................................... 53
4.1 Connection String.................................................................................................................................................. 53
4.1.1 Main String parameters ................................................................................................................................ 53
4.1.2 Extended Properties...................................................................................................................................... 53
4.1.3 Parameter BULK_METHOD ........................................................................................................................... 58
4.1.4 Parameters for Redshift ................................................................................................................................ 58
4.1.5 Deprecated and not supported parameters ................................................................................................. 58
4.2 Data type mapping between PostgreSQL and OLE DB ......................................................................................... 58
4.3 Internal Stored Procedures ................................................................................................................................... 60
4.3.1 Get License Information ................................................................................................................................ 60
4.3.2 Refresh Metadata Cache ............................................................................................................................... 60
4.3.3 Check license ................................................................................................................................................. 60
4.3.4 Publish comment into PGNP Profiler log ...................................................................................................... 60
5 Appendix A. Utilities...................................................................................................................................................... 62
Page 4
5.1 CreateIndex ........................................................................................................................................................... 62
5.2 DropIndex.............................................................................................................................................................. 67
5.3 PGNP Profiler (1.3.x and later) .............................................................................................................................. 71
5.3.1 User interface explained ............................................................................................................................... 71
5.3.2 Main actions in the profiler........................................................................................................................... 72
5.3.3 Collecting trace from remote computers ..................................................................................................... 72
5.3.4 Filtering messages in the trace ..................................................................................................................... 74
5.3.5 Format of PGL file.......................................................................................................................................... 76
5.3.6 Registry keys for advanced features ............................................................................................................. 79
5.4 PGNPUpdate (1.4.x and later) ............................................................................................................................... 80
5.4.1 Working in Normal mode .............................................................................................................................. 80
5.4.2 Working in Activation mode ......................................................................................................................... 81
5.4.3 Granting permissions to OLE DB provider for special users ......................................................................... 82
5.4.4 Using from command line ............................................................................................................................. 84
6 Appendix B. Handling ISequentialStream in the OLEDB provider................................................................................. 86
7 Appendix C. Samples ..................................................................................................................................................... 86
7.1 C# Samples ............................................................................................................................................................ 86
7.2 C++ Samples .......................................................................................................................................................... 88
7.3 Delphi 7 Samples ................................................................................................................................................... 89
8 Appendix D. Time zones conversion ............................................................................................................................. 89
Page 5
1 Introduction
The PGNP Native OLE DB Provider exposes powerful low-level OLEDB interfaces to Windows applications connecting to
PostgreSQL, Greenplum and Redshift databases. The provider can help you achieve performance and flexibility that are
not available via either ODBC driver(s) or .NET Provider(s):
• Rich metadata (advanced schema and cursors)
• Databases transformation support
• Linked Servers
• Replication
• Database Reverse Engineering
• Bulk import
The Developer’s Manual describes the Provider functionality and gives examples of the Provider usage. It is intended for
use by software developers, system administrators and users of the OLE DB applications.
The supported operating systems are: Windows Server 2000 with MDAC 2.8 SP1, Windows Servers 2003-2022, Windows
7 and later; both 32-bit and 64-bit.
The PGNP Provider works with the following versions of PostgreSQL database: PostgreSQL 8.0 and later, Greenplum 3.0
and later, EnterpriseDB Advanced Server 8.3 and later, Redshift, and with many other Postgres-compatible databases
(e.g. Yellowbrick, Amazon RDS, Heroku). It may work on earlier versions of the corresponding databases but we have not
tested those configurations. The Postgres and Greenplum Providers are available in two editions: Desktop Edition (DE)
and Server Edition (SE). Redshift Provider offers subscriptions starting v1.5. The following table summarizes differences:
Postgres DE Postgres SE
Intended for use from desktop applications connecting to Intended for use from servers (IIS, SSAS, SSIS, SSRS, linked
Postgres databases only. This edition may not be as fast and as servers, etc.) connecting to Postgres databases only. Optimized
scalable as Postgres SE on very large rowsets (over a million for extremely large rowsets, supports two phase commit
rows). protocol (DTC enlistment), and provides better integration with
SSIS.
Greenplum DE Greenplum SE
Intended for use from desktop applications connecting either to Intended for use from servers (IIS, SSAS, SSIS,SSRS, linked
Postgres or Greenplum. Handles distribution policies, able to servers, etc.) connecting to Postgres and Greenplum databases.
work with Greenplums’ forward-only cursors, utilizes gpload. Optimized for extremely large rowsets, supports two phase
This edition may not be as fast and as scalable as Greenplum SE commit protocol (DTC enlistment), and provides better
on very large rowsets (over a million rows). integration with SSIS.
Redshift
Intended for use from any applications connecting to Redshift. Supports cursors and FastLoad via S3. The Redshift Provider can be
installed side by side with either Postgres or Greenplum OLE DB providers. Supports SSO logins.
Note: Server Edition (SE) has all the features of Desktop Edition (DE), and adds more features as shown in the table above.
Page 6
2 Installation and Product Activation
To install the PGNP OLEDB Provider launch the installation module. The Module name may vary depending on the
provider variant/edition:
First page of the installation application is shown below. Click Next through the wizard pages.
Page 7
Enter the Product Key (License Key). The installation module will automatically activate the product on the computer.
This step requires an Internet connection. If Internet connection is not available, or you prefer to activate the product
later, select the check box on the bottom of the page (Register the product later using PGNPUpdate utility). Please refer
to section 2.1.3 “Activation on a computer behind a firewall (in DMZ)”.
Page 8
Click the Standard, Next, Install and Finish buttons in the following dialogs.
Note. The checkboxes in the final dialog are optional, and can be used for
either an immediate check of the license activation status, and/or for
running PGNPUpdate tray application each time the system starts. The
tray application will display the license activation and the subscription
status.
Page 9
2.1.2 Determining the installed version of the PGNP provider
To determine the installed version of the PGNP provider run appwiz.cpl from a command line (or go to Start->Control
Panel->Programs and Features/Add or Remove Programs). Line starting with “Intellisoft OLEDB Provider” contains
version and build number, e.g. “1.5.0.4000”.
The provider version can also be determined programmatically via call to pgnp_getlicenceinfo() stored procedure.
Note: add parameter /l*V pgnp15.txt in order to store the verbose installation log. It can be used for troubleshooting
issues during the installation.
Page 10
For details about the PGNPUpdate utility, please refer to section 5.4.2.
To check that the product is properly activated, please launch the PGNPUpdate or the PGNProfiler utility. The utilities
should display valid registration information (PGNProfiler will display the info in the About dialog).
3 Provider’s Features
This chapter contains information about various features and use cases of the Provider.
3.1.1 Transforming MS SQL 2000 database into a PostgreSQL database using DTSWizard
1. Make sure MS SQL Server 2000 is running and source database available.
2. Create an empty destination database in PostgreSQL.
3. Launch DTSWizard.exe (e.g. from C:\Program Files (x86)\Microsoft SQL Server\130\DTS\Binn\), and select
source database. Click Next.
Page 11
4. Select “Intellisoft OLE DB Provider for PostgreSQL” from the “Destination” combo-list, click Properties button
and specify connection parameters of the destination database. Click Next.
5. Select “Lower Case Schema” to convert tables and columns names into lower case (recommended):
Page 12
6. Click Next button on the “Specify Table Copy or Query” page.
7. Select tables and views you want to be copied to destination database. Click Next.
Page 13
8. Choose “Run Immediately” and click Next. Click Finish.
To convert indexes, use CreateIndex utility. See more information in Utilities chapter of the Manual.
3.1.2 Transforming MS SQL 2005, 2008, 2012 database into a PostgreSQL database using DTSWizard
The database transformation procedure between SQL Server 2005, 2008, 2012 and Postgres, Greenplum, Redshift is
similar to the one described above. Launch SQL Server Import and Export Wizard, and specify OLEDB source and
destination.
3.2 Transactions
The PGNP provider supports standard OLE DB transactions (Local transactions), COM+ Distributed transactions (starting
version 1.3.0), PostgreSQL nested transactions via direct OLEDB calls or SQL commands, and “savepoints”.
Page 14
Debug.Assert(1 == cmd_insert.ExecuteNonQuery());
// rollback
nested_trans2.Rollback();
// check that the record was not removed from the nested transaction level 2
OleDbCommand cmd_check = new OleDbCommand("select count(*) from contact where lname=?", con1, nested_trans);
cmd_check.Parameters.AddWithValue("?", "Blah");
Debug.Assert(1 == Convert.ToInt32(cmd_check.ExecuteScalar()));
trans.Commit();
con1.Close();
Starting version 1.3.0 PGNP supports nested transactions. Note, since ADO does not support nested transactions, you
can use them from either OLE DB or ADO.NET (see C# Sample 26). To enable nested transactions, specify
NESTED_TRANS=ON in Extended Properties parameter of the connection string.
PGNP provider triggers transactions related events on the Connection object: BeginTransComplete,
CommitTransComplete, RollbackTransComlete.
// start transaction
fConn.BeginTrans; // note: PGNPBeginTransComplete callback is called from provider
...
// some useful work
...
if Res then
fConn.Commit // note: OnCommitComplete callback is called
else
fConn.Rollback; // note: OnRollback callback is called
Page 15
3.2.2 Distributed Transactions
Distributed transactions allow coordinating database transactions among multiple databases or transactional systems.
PGNP Provider supports transactions enlistment in Distributed Transactions Coordinator (DTC) and handles events from
the DTC. Note: distributed transactions support added to PGNP 1.3.0 and later.
One of the scenarios that require distributed transactions is when you need to pull data from two dependent constantly
changing tables in SSIS, so that when it’s imported on MSSQL side the data is in consistent state. You can configure the
Integration Services project with a Control Flow property “Transaction Option” equal to “Require”.
namespace DistribTrans
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
sb.Append("Provider=PGNP.1;");
sb.Append("Persist Security Info=True;");
sb.Append("Data Source=localhost;"); // PostgreSQL server;
sb.Append("Initial Catalog=postgres;"); // Database name
sb.Append("User ID=postgres;"); // User name
sb.Append("Password=12345;"); // User password
sb.Append("Extended Properties=\"PORT=5432;\"");
Page 16
3.2.3 PostgreSQL Nested Transactions
ADO does not support nested transactions. However, PostgreSQL nested transactions can be used by calling OLEDB
interfaces or executing START TRANSACTION, SAVEPOINT and other SQL commands. To enable nested transaction
support in PGNP provider add NESTED_TRANS=ON parameter to Extended Properties of a connection string. Note:
nested transactions support added to PGNP 1.3.0 and later.
The PGNP provider recognizes transaction related SQL commands and tracks internal transaction state automatically.
The following C# example demonstrates nested transactions and isolation levels use:
//
// Transaction isolation level defines visibility of changes among different parallel transactions.
//
// The isolation level can be set with System.Data.IsolationLevel parameter in call to
// OleDbConnection.BeginTransaction().
//
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Text;
using System.Diagnostics;
namespace NestedTrans
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
sb.Append("Provider=PGNP.1;");
sb.Append("Persist Security Info=True;");
sb.Append("Data Source=localhost;"); // PostgreSQL server;
sb.Append("Initial Catalog=postgres;"); // Database name
sb.Append("User ID=postgres;"); // User name
sb.Append("Password=12345;"); // User password
sb.Append("Extended Properties=\"NESTED_TRANS=ON;\""); // Enable nested transactions
Page 17
// Delete the record in first nested transaction
cmd_delete.Transaction = internal_transaction;
Debug.Assert(1 == cmd_delete.ExecuteNonQuery());
// Commit changes
internal_transaction.Commit();
trans.Commit();
con1.Close();
}
}
}
To create a linked server, launch Enterprise Manager 2000 or Management Studio 2005/2008/2012. Right click on
Security/Linked Servers or Server Objects/Linked Servers and select “New Linked Server…” menu item. Enter the Linked
Page 18
server name and choose “PostgreSQL Native Provider” in “Other Data Sources”/Provider combo box. Enter your product
name, Postgres server, Extended Properties of the connection string and database name as shown:
In “Security” tab select “Be made using this security context” radio button and enter credentials to access Postgres
database. Click OK. The Linked Server is created.
Page 19
You can query or change data using SQL commands like:
SELECT * FROM “MYLINKEDSVR”.”postgres”.”public”.”contacts”
Note, “openquery” syntax allows using of PostgreSQL-specific statements. Refer to MSDN documentation for more
details. Please remember using double quotes if your PostgreSQL schema is in mixed case.
Execute following SQL statements to create a linked server with name 'PGNP_SAMPLES':
declare @LINKED_SERVER_NAME varchar(max);
declare @PRODUCT_NAME varchar(max);
declare @PGPROVIDER varchar(max);
declare @DATA_SOURCE varchar(max);
declare @CN_STR varchar(max);
declare @SAMPLE_CATALOG varchar(max)
Page 20
3.3.3 Viewing and changing Linked Server RPC status
Some SQL commands sent to a linked server require RPC configuration. For example, following command:
EXEC ('CREATE TABLE contact(Id INT NOT NULL, LNAME VARCHAR)') AT PGNP_SAMPLES
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{3170DFF1-4803-42a0-A1B3-D14656857070}]
"DllSurrogate"="C:\\Windows\\SysWow64\\dllhost.exe"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{3170DFF1-4803-42a0-A1B3-D14656857071}\InprocServer32]
@="C:\\Program Files (x86)\\Intellisoft\\PGNP\\PGNP64.dll"
"ThreadingModel"="Both"
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\AppID\{3170DFF1-4803-42a0-A1B3-D14656857070}]
"DllSurrogate"="C:\\Windows\\SysWow64\\dllhost.exe"
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\CLSID\{3170DFF1-4803-42a0-A1B3-D14656857071}\InprocServer32]
@="C:\\Program Files (x86)\\Intellisoft\\PGNP\\PGNP.dll"
"ThreadingModel"="Both"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{3170DFF1-4803-42a0-A1B3-D14656857070}]
"DllSurrogate"="C:\\Windows\\System32\\dllhost.exe"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{3170DFF1-4803-42a0-A1B3-D14656857071}\InprocServer32]
@="C:\\Program Files\\Intellisoft\\PGNP\\PGNP.dll"
"ThreadingModel"="Both"
Page 21
For 64bit PGNP provider (Redshift):
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{FFCCB099-E3D0-4FFC-87F9-AC3FAAF91270}]
"DllSurrogate"="C:\\Windows\\SysWow64\\dllhost.exe"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{FFCCB099-E3D0-4FFC-87F9-AC3FAAF91271}\InprocServer32]
@="C:\\Program Files (x86)\\Intellisoft\\RSNP\\PGNP64.dll"
"ThreadingModel"="Both"
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\AppID\{FFCCB099-E3D0-4FFC-87F9-AC3FAAF91270}]
"DllSurrogate"="C:\\Windows\\SysWow64\\dllhost.exe"
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\CLSID\{FFCCB099-E3D0-4FFC-87F9-AC3FAAF91271}\InprocServer32]
@="C:\\Program Files (x86)\\PGNP\\PGNP.dll"
"ThreadingModel"="Both"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{FFCCB099-E3D0-4FFC-87F9-AC3FAAF91270}]
"DllSurrogate"="C:\\Windows\\System32\\dllhost.exe"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{FFCCB099-E3D0-4FFC-87F9-AC3FAAF91271}\InprocServer32]
@="C:\\Program Files\\Intellisoft\\RSNP\\PGNP.dll"
"ThreadingModel"="Both"
2. Run DCOMCNFG.exe utility. Expand "Component Services", "Computers", "My Computer" and select "DCOM Config"
folder. In the right pane find application named "{3170DFF1-4803-42a0-A1B3-D14656857070}" (or in Redshift case
"{FFCCB099-E3D0-4FFC-87F9-AC3FAAF91270}"), right-click and select Properties. Configure Security and Identity in the
corresponding tabs. Default values could work in many cases. Close the utility.
3. In SQL Server Management Studio uncheck "allow inprocess" option in PGNP provider properties. The changes are
immediate and usually do not require restart of SQL Server or the computer. Alternatively the following stored
procedure can be executed:
EXEC master.dbo.sp_MSset_oledb_prop N'PGNP.1', N'AllowInProcess', 0
Perform a query for the Linked Server. If issue occurs see Events Viewer for errors information (e.g. run eventvwr.msc
from command prompt). If a test query succeeded you can use Process Explorer (http://www.sysinternals.com) to find
which surrogate process hosts the PGNP provider DLL.
Page 22
Specify location for snapshots:
Accept default settings on the next page for simplicity (or choose custom setting). The server is configured as
Distributor:
Page 23
Choose “Snapshot” or “Transactional” publication type (“Merge” is not supported yet”):
Page 24
Choose all tables for replication:
Click on the ellipses for every table and review properties (optional):
Page 25
Click Next button “Create Publication Wizard” dialog until:
Page 26
Click “Run Agent Now” button to create the snap shot files.
Click “Configure Publishing, Subscribers and Distribution…” menu item under main menu Tools->Replication and select
Subscribers tab. Click “New…” button and select “OLEDB data source”:
Page 27
Then choose the subscriber (for instructions on how to create linked server see Chapter “Linked Servers” in this manual).
Here are screenshots of the Linked Server configuration:
Page 28
Click “OK” button in Publisher and Distributor Properties dialog:
Right click on <Server>/Replication/Publications/pubsPublication:pubs and click “Push New Subscription” menu item to
run the New Subscription wizard. Choose the newly created subscriber and the default destination for the
Heterogeneous Subscribers:
Page 29
Then set Distribution Agent schedule:
Choose “Yes, initialize the schema and data” option and “Start … immediately” check box:
Page 30
Click Next and Finish:
3.4.5 Synchronize
Right click on the PGPUBS:(default destination) item and select “Start Synchronization” menu item:
Page 31
Page 32
3.5 Replication with SQL Server 2005/2008/2012
MS SQL Servers 2005/2008/2012, unlike SQL Server 2000, do not have the user friendly graphical interface for
replication configuration. However, the replication can be configured via SQL stored procedures in SSMS.
Page 33
Please double check that “Allow inprocess” box is checked in Server Objects\Linked Servers\Providers\PGNP\Properties
dialog (access it via treeview pane on the left in the SSMS).
Note: the @pre_creation_cmd parameter can be set to N'drop' if table already exists, and needs to be dropped.
Page 34
@subscriber_type = 3
To create first snapshot and start replication, open Replication Monitor (right-click on Replication\Launch Replication
Monitor), then select pgnpsnap1 publisher on the left, right-click Snapshot Agent line in “Warnings and Agents” tab and
click “Start Agent”:
Page 35
3.5.6 Deleting subscription and publication
Following commands can be used for deleting previously created subscription and/or publication:
exec sp_dropsubscription @publication = N'pgnpsnap1', @article = N'all', @subscriber = N'<postgres-host>';
The steps above described snapshot replication configuration. To configure transactional replication perform following
steps instead of steps 2.5.4 and 2.5.5.
Page 36
For each table <table-name> execute following command:
exec sp_addarticle @publication = N'pgnptrans1', @article = N'<table-name>',
@source_owner = N'dbo', @source_object = N'<table-name>', @type = N'logbased',
@description = null, @creation_script = null, @pre_creation_cmd = N'none', @schema_option = 0x000000000803509D,
@identityrangemanagementoption = N'manual', @destination_table = N'<table-name>', @destination_owner = N'dbo',
@vertical_partition = N'false'
GO
Page 37
@frequency_recurrence_factor = 0, @frequency_subday = 0,
@frequency_subday_interval = 0, @active_start_time_of_day = 0,
@active_end_time_of_day = 235959, @active_start_date = 20090715,
@active_end_date = 99991231, @enabled_for_syncmgr = N'False',
@dts_package_location = N'Distributor'
GO
Page 38
3.6 Generating reports in SQL Server Reporting Services
Navigate to the Report Manager in the Internet Explorer using a URL, e.g. http://localhost/Reports_SQL11 (where SQL11
is the name of the SLQ Server database instance; it could be different).
Launch the Report Builder, and create “New Report” using “Table or Matrix Wizard”. Create new OLE Data Source, and
specify connection parameters to the Postgres database. For the Dataset use following command:
="select * from [DimEmployee] where [Title] in ('" & JOIN(Parameters!TitlePrm.Value, "','") & "') "
Choose columns to populate in the report. Then create the report parameter as shown below:
Note: The OLE DB standard says that multiple parameters can be used only with commands that do not return rowsets.
This is the reason why we must use IN clause and the JOIN function to pass multiple parameters. Otherwise SSRS will
Page 39
display the error: “Cannot add multi value query parameter 'prm' for dataset 'DataSet1' because it is not supported by
the data extension. (rsErrorAddingMultiValueQueryParameter)”.
Page 40
3.7 Two phase commit protocol (2PC)
PGNP Provider implements support for 2PC. You will need to configure and run Distributed Transaction Coordinator.
Navigate to Security tab and make sure that “Enable XA Transactions” checkbox is selected. “Network DTC Access”,
“Allow Inbound” and “Allow Outbound” must be selected as well. Please read MSDN articles for more details on
configuring DTC.
Click OK in the Local DTC Properties dialog and restart DTC service (see the next paragraph).
If the following error is returned: “MSDTC XARMCreate error”, please check if the following registry keys exist:
Page 41
HKLM\Software\Wow6432Node\Microsoft\MSDTC\XADLL\PGNP.DLL=<path>
HKLM\Software\Microsoft\MSDTC\XADLL\PGNP64.DLL=<path>
The key is created automatically when the provider is enlisting in a distributed transaction for the first time. The
provider may not be able to create the key depending on the parent process security context. In this case, either
manually create the keys, or set proper security permissions on the registry folder, and restart the distributed
transaction. For example, grant “Network Service” account permissions for full access to
HKLM\Software\Microsoft\MSDTC\XADLL, if DTC runs under the “Network Service” account.
Page 42
Regular PGNP Provider name used in a connection string is “PGNP”. But the “BI Alias” name is “SQLOLEDBPGNP”. This is
needed because of undocumented Microsoft implementation which enables various features only to providers with
names started with “SQLOLEDB”.
Also create a connection to a SQL Server database with source data (using “SQL Server Native Client”).
Proceed by configuring column mapping. Then execute the package, and check the result of the rows copying. Note, that
PGNP Profiler will show something like the following:
Page 43
3.9 The Query Optimizer
The Query Optimizer is a built-in mechanism to transform SQL queries in the PGNP Provider. It can be used to
troubleshoot performance issues in large databases without a need to change SQL in an application. The Optimizer is
closely integrated with PGNP Profiler (see 5.3 in Appendix A. Utilities). User can define rules for replacing SQL queries
“on the fly”. The rules can use Exact Match, or Template Match modes for optimizing the queries.
In Exact Match mode, an application query is replaced with the “optimized” query only when the application query is the
same as one specified in a rule.
In Template Match mode, an application query is replaced with the “optimized” query when the application query
matches a query in a rule so that any numerical constants or literals ignored.
To enable Optimizer add OPTIMIZER=ON to the Extended Properties of the Connection String.
The Optimizer uses a special table to store configuration. It can be created manually by executing the statements shown
below, or let the PGNP Profiler automatically create it (recommended).
In PGNP Profiler select menu “View”->“Options…”, and click ellipsis in the Query Optimizer’s Connection string:
Page 44
In the Data Link Properties dialog, configure the connection to a database where queries optimization should be
performed. Click OK in the Options dialog, and the pgnp_optimizer table will be created automatically. To disable Query
Optimizer uncheck the “Enable” option in the dialog.
In the Optimizer dialog replace the original statement with “SELECT 4+5”, keep “Exact Match” method, and optionally
enter any description as shown below:
Page 45
Click OK, execute the original statement again (SELECT 2*3), and locate new trace entry in the PGNP Profiler. Notice, that
result is now equal to 9, and the Profiler shows how the statement was substituted:
In the Optimizer dialog replace original statement with “SELECT $4+$1 AS id, $2, $3”, set “Template Match” method, and
optionally enter some description as shown below:
Page 46
In the Template Match mode integer, floating point and string constants from original query will be passed “into
parameters” of the template.
Execute original statement, or a statement with different constants, and locate new trace entry in the PGNP Profiler. The
Profiler shows how the statement was substituted:
As shown on the picture above, a query with different constants was executed: “SELECT x.id+1000 AS id, 'Fee', 19.99
FROM (SELECT 5 AS id) AS x”.
Run the ROLAP cube and locate slowest query in the PGNP Profiler’s trace:
Page 47
Copy the Client SQL from the “details view”. Here is a simplified representation of the slow query:
Create materialized view as shown below. Notice, the parameterized conditions (marked with yellow background) were
removed from the query.
Right click mouse on the slow query, and select “Optimize Query…” menu item.
Keep the “Exact Match” method; click OK in the Optimizer dialog. Then run the cube again, locate the corresponding
trace entry in the Profiler, and see that execution is now significantly faster. In our test with 400 million rows fact table,
acceleration was more than 100.
Run application, and locate slow schema query in PGNP Profiler’s trace:
Copy “Executed SQL” from the Details view, and create a materialized view as shown below:
Page 48
"COLUMN_DEFAULT" from pg_attribute A inner join pg_class C on (A.attrelid=C.oid) inner
join pg_tables T on (C.relname=T.tablename) inner join pg_namespace NS on
(NS.oid=C.relnamespace and NS.nspname=T.schemaname) inner join pg_type TY on
(TY.oid=A.atttypid) left outer join pg_attrdef D on (D.adrelid=C.oid and
D.adnum=A.attnum) where A.attnum>0 and A.attisdropped='f' union all select T.schemaname
as "TABLE_SCHEMA", T.viewname as "TABLE_NAME", A.attname as "COLUMN_NAME", A.attnum as
"ORDINAL_POSITION", A.atthasdef as "COLUMN_HASDEFAULT", A.atttypid as "DATA_TYPE",
TY.typname as "TYPNAME", A.attnotnull as "NOT_NULL", A.attlen as "FIELD_LENGTH",
A.atttypmod as "FIELD_MOD", D.adsrc as "COLUMN_DEFAULT" from pg_attribute A inner join
pg_class C on (A.attrelid=C.oid) inner join pg_views T on (C.relname=T.viewname) inner
join pg_namespace NS on (NS.oid=C.relnamespace and NS.nspname=T.schemaname) inner join
pg_type TY on (TY.oid=A.atttypid) left outer join pg_attrdef D on (D.adrelid=C.oid and
D.adnum=A.attnum) where A.attnum>0 and A.attisdropped='f') s where "TABLE_SCHEMA"=[…] and
"TABLE_NAME"=[…] order by "TABLE_SCHEMA", "TABLE_NAME", "ORDINAL_POSITION"
Note: conditions marked with red color should be removed. Right click mouse on the entry, select “Optimize Query…”
menu item, and replace statement as shown below:
Re-run the application, and locate the schema query. Here is result of the statement substitution:
Page 49
3.10 “Hinting” statements
The Microsoft SQL Server provides both short-characters (“text”) and wide-characters (“ntext”) column types, while
both Postgres and Greenplum – only short-character (“text”). Microsoft left it to a higher level application to recognize
the type of a column, and pass either single-character or wide-character streams in ISequentialStream. However, the
stream itself does not specify what types of characters are in it. By historical reason, the PGNP provider handles stream
data as short-characters. This may result in issues when only first character is copied, etc.
To address the issue of characters streams handling, the PGNP OLE DB provider memorizes table creation statements,
and uses the knowledge for interpreting ISequentialStream. Below we describe two real-life scenarios.
Then launch DTSWizard, for the source choose SQL Native Client, and select TestHint1 table, for destination choose a
Postgres/Greenplum database, and optionally configure Copy parameters. Click button “Edit Mappings…” and the “Edit
SQL…”. Leave the SQL text as is:
When the test package executed, the PGNP Profiler shows following:
Check result, and see that all values were copied correctly:
Page 50
3.10.2 Tweaking Data Flow in SSIS Package
Let us consider another example: copying flat file with Unicode text to Postgres in SSIS. Create UTF-16 text file
containing any text, for example – with Portugese special characters:
ãáàâçéê€,íõóôúü«»
ÃÁÀÂÇÉÊ€,ÍÕÓÔÚÜ
In the SSIS package add new Flat File Connection, point it to the text file, uncheck “Column names in the first data row”.
Add Flat File Source to the Data Flow, then add OLE DB Command as shown below:
The OLE DB Command is used for hinting the PGNP Provider that columns will receive wide-characters from SSIS. The
clause IF NOT EXISTS can also be used with Greenplum DB. The PGNP Provider for Greenplum will remove the clause,
but if error “table already exists” is returned, it will convert it into success code.
Add OLE DB destination (with optional FastLoad), select destination table portugese_test, and map columns:
Page 51
Execute package and check the resulting data.
Example 2. Cursor could be enabled and minimum fetch rows set to a new value:
--PGNP:CURSOR=ON;MIN_FETCH_ROWS=5000;
SELECT * FROM TABLE2
Here are properties that can be changed per statement in builds 1.4.0.3606 and later: CURSOR, MIN_FETCH_ROWS,
COMMAND_TIMEOUT, NUM_PRECISION, NUM_SCALE, ZERO_TS_FRACTION.
Page 52
4 Programming with the Provider
4.1 Connection String
PGNP connection string consists of a list of name=value pairs separated by semicolon, e.g.:
Provider=PGNP.1;User ID=postdba;Password=montreal;
Initial Catalog=aloha;Data Source=bbox;
Extended Properties=”PORT=5432;COMMAND_TIMEOUT=900;”;
Data Source String All Yes PostgreSQL server host name or IP address
Connect Timeout Integer 1.3.0 No 15 Connect timeout in seconds. Zero is used for indefinite timeout.
Extended Properties String All No Extended parameters list in double quotes. See details below.
Application Name String 1.4.0.3420 No Passes application name to the underlying DBMS.
* Note: A special reserved value “$NO_CATALOG” can be used for the Initial Catalog. It allows creating OLEDB session without connecting to a
database. Only two stored procedures are working in the NO_CATALOG mode: pgnp_getlicenseinfo and pgnp_checklicense.
CURSOR Boolean 1.4.0.3170 ON When set to ON the provider uses cursors to query and change
data. Main advantage of using cursors is lower memory
consumption on client side. However, since cursors work only
inside transaction (that can be automatically created by the
provider), it may result in undesirable side-effects. Other
supported values: OFF and SINGLEROW. When OFF entire
rowset is loaded into memory. The SINGLEROW allows
processing of unlimited size rowsets (for ETL and Analytics), but
does not support scroll-back and fetch-back modes.
LowerCaseSchema Boolean All OFF If ON, automatically convert all schema into lower case, e.g.
Create table “MiXed” () will be transformed into
Create table “mixed” ()
This parameter is used mostly during Database Transformation
of a case insensitive database, such as MS SQL, into PostgreSQL.
SYNTAX String 1.3.0 Pass-Through Reserved. Specifies which SQL syntax the Provider should expect
as input:
Pass-Through – for PostgreSQL compatible syntax;
T-SQL – MS SQL Server 2005 compatible syntax; or
Oracle – Oracle 10g2 compatible syntax.
The Provider converts input statements into PostgreSQL
Page 53
compatible statements.
SEARCH_PATH String 1.2.8.1107 $user,public “Specifies the order in which schemas are searched when an
and later object (table, data type, function, etc.) is referenced by a simple
name with no schema component.” See description of
search_path parameter in
http://www.postgresql.org/docs/8.3/interactive/runtime-
config-client.html for more details. Example of when the use of
this parameters can be useful is a DTS package.
FORCECP String 1.4.0.3264 The code page identifier is used for the conversion of Postgres
or data into Windows Unicode (UTF-16). One of the predefined
Integer strings (see below), or and integer can be used. By default, the
provider uses “client_encoding” parameter of the Postgres
database. In some case using this parameter can fix conversion
issues. For example, when SQL_ASCII database stores characters
with values larger than 127, the parameter can be set as
WIN1252 for correct conversion.
List of supported CP names: BIG5, EUC_CN, EUC_JIS_2004,
EUC_JP, EUC_KR, EUC_TW, GB18030, GBK, ISO_8859_5,
ISO_8859_6, ISO_8859_7, ISO_8859_8, JOHAB, KOI8, LATIN1,
LATIN2, LATIN3, LATIN4, LATIN5, LATIN6, LATIN7, LATIN8,
LATIN9, LATIN10, SHIFT_JIS_2004, SJIS, SQL_ASCII, UHC, UTF8,
WIN1250, WIN1251, WIN, WIN1252, WIN1253, WIN1254,
WIN1255, WIN1256, WIN1257, WIN1258, TCVN, WIN866, ALT,
WIN874.
An integer value can be used for the CP, e.g. 1252 instead of
WIN1252.
CNV_SPECIAL_FLTVAL Boolean 1.3.0 OFF When OFF – no conversion of special floating point values
(INFINITY, NaN, etc.) is performed when reading Real and Float
fields from database.
When ON – the following conversion is performed:
* ‘Infinity’ is converted into MAX float 3.402823466e+38F
or double 1.7976931348623158e+308;
* ‘-Infinity’ is converted into negative max float or double;
* NaN is converted into zero.
We recommend turning this option ON when working with
Linked servers.
NESTED_TRANS Boolean --- OFF When OFF – nested transactions are not allowed.
When ON – allow nested transactions.
This was implemented by request of some customers in 1.2.8
and currently disabled in all versions. In 1.3.x nested
transactions are allowed by default.
SSL String 1.3.0 Prefer SSL parameters. Allowed values: Require, Prefer, Disable, or
Allow.
SSLCERT String 1.4.0.3612 %APPDATA% File name of the client SSL certificate.
\postgresql
\postgresql.crt
SSLKEY String 1.4.0.3612 %APPDATA% Secret key used for the client certificate.
\postgresql
\postgresql.key
Page 54
SSLROOTCERT String 1.4.0.3612 %APPDATA% File containing SSL certificate authority (CA) certificate(s).
\postgresql
\root.crt
SSLCRL String 1.4.0.3612 %APPDATA% File name of the SSL certificate revocation list.
\postgresql
\root.crl
BULK_INSERT Integer 1.2.8.1110 1 Specifies the number of rows for bulk insert (e.g. during
DTS/SSIS data import). Valid range is 1..1000000. See
BULK_METHOD below for details on how this parameter is used.
Normally the larger the number the less roundtrips performed
for data insertion.
BULK_METHOD String 1.3.0 Values Bulk insert method: COPY, PIPECOPY, GPLOAD and VALUES. For
more details read a paragraph below.
TEXT_AS_LONGVARCHAR Boolean 1.3.0 ON If this parameter is set to OFF then Provider returns Text BLOBs
as Strings. This parameter can be used when migrating
PostgreSQL ODBC applications to PGNP.
ACCEPT_CERT String 1.3.0 <none> MD5 hexadecimal sum of the PostgreSQL certificate. This
parameter can be used to avoid server certificate validation
dialog and basically tells Provider to accept the specific
certificate temporarily for the current session.
ZERO_TS_FRACTION Boolean 1.3.0 OFF When the parameter is set to ON, the Provider zeroes
timestamp fraction in rowset fields. This addresses Datetime
overflow issue when transforming databases in SSIS.
USE_TIME2 Boolean 1.4.0.3330 ON When the parameter is set to OFF, the provider returns time
and timetz fields types as legacy ADO time (DBTYPE_DBTIME).
Otherwise, the provider handles the fields as time with
microseconds precision (DBTYPE_DBTIME2).
SQLSERVER Integer 1.3.0 2005 Setting this parameter to 2005, 2008 or 2010 exposes provider’s
type system differently to support database transformations
between PostgreSQL and corresponding versions of SQL Server.
For example, when set to 2005 PostgreSQL types date and time
are handled as SQL Server’s datetime; when 2008 – support for
new SQL Server types datetime2, time2, interval,
datetimeoffset is added.
MIN_FETCH_ROWS Integer 1.3.0 100 Specifies how many rows should be fetched in PostgreSQL
Server Side cursor. Valid range is 1..1000000. If an invalid value
is specified, then default value is used. It is recommended to use
value of 2000 or larger for tables with millions of rows (to
reduce number of round-trips for fetching the data).
HTTP_PORT Integer Greenplum 8081 The HTTP port on which gpfdist.exe will serve files.
only
NIC_ADDR String Greenplum <none> List of IP addresses if the computer has multiple NICs, e.g.
only NIC_ADDR=10.20.30.40,10.20.30.41,10.20.30.42
Page 55
DISTINCT_VALUES String Greenplum DISTINCT When non-default value is used (GROUPBY) the provider adds to
only queries with the DISTINCT clause the following clauses: GROUP
BY 1,2. This parameter may be used for performance.
FORCE_SORTED_LOV String Greenplum NO When non-default value is used (YES) the provider adds to
only queries with the DISTINCT clause the following clauses: ORDER
BY 1,2. Works only with DISTINCT_VALUES=GROUPBY. This
parameter may be used for performance.
EVENTS String 1.4.0.3132 ALL When default value is used (ALL), OLEDB Provider subscribes to
all events, including metadata and optimizer hints change
events. To disable subscribing to any events use NONE. Other
values are reserved for future use. Provider triggers events each
time metadata or optimizer hints change occurs despite of the
parameter.
FAILOVER String 1.4.0.3594 Comma-separated list of failover servers. Each entry in the list
can have colon separated host name or IP address, port,
number of retries, and delay in milliseconds. Example:
10.11.12.9:5432:1:500, hostalt2:5444.
AWS_S3_HEADER String Redshift Amazon S3 PUT header parameters used for FastLoad and
1.4.0.3456 BulkInsert. For example, add “AWS_S3_HEADER=x-amz-server-
side-encryption:AES256;” to allow SSE-S3 at-rest data
encryption. Multiple parameters can be specified separated by
comma, and they will be passed on separate lines in the header.
SET <name> String 1.4.0.3430 Used for passing SET command(s) that will be executed by the
OLEDB provider after connection is open Greenplum example:
set statement_mem='1999MB';set optimizer=on; (enables GP
Optimizer)
STREAM String 1.4.0.3440 SHORT Specifies how the OLEDB provider should handle
ISequentialStream. Default is SHORT, which means that
ISequentialStream will contain short-characters (8-bit). When
Page 56
set to WIDE, the provider handles the stream as containing
wide-characters (16-bit Unicode).
SQL_PROLOG String 1.4.0.3456 Path to file with SQL commands that should be executed
immediately after connection is open. The prolog file can used
for initial configuration of the connection.
TIMEZONE String 1.4.0.3456 Specifies target time zone in which the TIMESTAMP WITH
TIMEZONE (timestamptz) values should be converted. By
default, the OLEDB provider converts timestamptz values into
the local time zone on the PC. For example,
“TIMEZONE=Singapore” will display values in Singapore time.
For details refer to Appendix D.
The Extended Properties could be loaded from Registry instead of the connection string. The PGNP Provider loads the
properties in the following sequence:
1) From HKLM\SOFTWARE\Wow6432Node\Intellisoft\RRS-15\ProviderString;
2) From HKCU\SOFTWARE\Wow6432Node\Intellisoft\RRS-15\ProviderString;
3) From the connection string.
Values obtained on later steps overwrite values from previous steps. The REG_DWORD/REG_QWORD types should be
used for Integer parameters, and for other parameters – RE_SZ. Registry values with other types are ignored.
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Intellisoft\RRS-15\ProviderString]
"COMMAND_TIMEOUT"=dword:00000000
"CURSOR"="ON"
"MIN_FETCH_ROWS"=dword:000007d0
"IDP_HOST"="sso.mycompany.biz"
"IDP_PORT"=dword:000001bb
"PREFERRED_ROLE"="arn:aws:iam::1234567890:role/production"
Page 57
4.1.3 Parameter BULK_METHOD
When set to ‘VALUES’ (default) then BULK_INSERT specifies number of value sets in the SQL command:
When set to ‘COPY’ then BULK_INSERT specifies number of rows buffered for COPY command.
When set to ‘PIPECOPY’, then multiple INSERT statements are combined into COPY command. This is special mode
designed for fast transactional replication.
When set to ‘GPLOAD’ then a Greenplum’s loader utility is used (gpload/gpfdist). ‘GPLOAD’ parameter is used only by
the Greenplum edition of the PGNP provider.
BULK_METHOD is an obsolete way of fast importing data into database. We recommend using FastLoad for fast data
import. However, PIPECOPY may be only an option when fast transactional replication is needed.
SSO/IDP logins to Redshift are allowed via use of the Extended Parameters IDP_HOST, IDP_PORT and PREFERRED_ROLE.
When SSO login is enabled the user/password are the AD user credentials (not Redshift).
Provider Data Type PostgreSQL Data Type OLE DB Data Type(s) OLE DB Type Name(s)
Page 58
real real
float(p), p<25 float(p), p<25
“Provider Data Type” column specifies data types that PGNP provider exposes to a user. These types are recognized in
CREATE and ALTER statements and substituted “on-the-fly” with corresponding PostgreSQL Data Type. These types are
used by MS Data Transformation Services Wizard database conversion.
Page 59
4.3 Internal Stored Procedures
The purpose of the provider’s internal stored procedures is to supply user application with additional services. Current
implementation includes procedures: to obtain the provider license information, to refresh metadata cache, check
license, publish comments into PGNP log, etc. In future more stored procedures are going to be written and even
support for custom third-party procedures can be added. Almost all stored procedures work even when no connection is
open to database (i.e. Initial Catalog=$NO_CATALOG).
pgnp_getlicenseinfo()
1 LICENSEDTO String Shows user name or company who purchased the product
2 TYPE String License type, i.e. Single User License or a License Pack
5 UPDATEDATE Date If this is an update of the product, then shows date, otherwise is NULL
6 SPECIAL String Unique identifier that uniquely identifies the product build
Page 61
5 Appendix A. Utilities
5.1 CreateIndex
Purpose of the CopyIndex utility is copying of indexes from source DB to a destination DB. Common use case: it can be
used after DTS/SSIS wizard or program package copied data between databases to append information about indexes.
USAGE:
CopyIndex.exe -s <.udl File> -d <.udl File> -a <string> [-i <string>] [-t <string>] [--] [-v] [-h]
--, --ignore_rest
Ignores the rest of the labeled arguments following this flag.
-v, --version
-h, --help
Displays usage information and exits.
Example 1. Copy all indexes from MSDB (MSSQL, dbo) to PGDB (Postgres, dbo).
CopyIndex.exe -s MSDB.udl -d PGDB.udl -a dbo
Example 2. Copy all indexes related to Employees table. Employees table should exist in source and destination DBs.
CopyIndex.exe -s MSDB.udl -d PGDB.udl -a dbo -t Employees
Example 3. Copy PK_Employees indexe in Employees table. Employees table should exist in source and destination DBs.
CopyIndex.exe -s MSDB.udl -d PGDB.udl -a dbo -t Employees -i PK_Employees
Page 62
typedef pair<wstring, CIndexDesc> PairIndexes;
void DisplayErrorInfo()
{
CDBErrorInfo errors;
ULONG errorCount;
HRESULT hr = errors.GetErrorRecords(&errorCount);
if (FAILED(hr))
{
cerr << "** ERROR: hr = " << hex << hr << endl;
return;
}
TCHAR filename[MAX_PATH];
GetModuleFileName(NULL, filename, MAX_PATH);
VersionInfo verInfo(filename);
try
{
CmdLine cmdline(verInfo.FileDescription(), ' ', verInfo.productVersion_str());
cmdline.parse(argc, argv);
srcUdl = sudlFileArg.getValue().c_str();
dstUdl = dudlFileArg.getValue().c_str();
bstrSchema = schemaArg.getValue().c_str();
bstrIndex = indexArg.getValue().c_str();
bstrTable = tableArg.getValue().c_str();
}
catch (ArgException &e)
{
cerr << endl << "** ERROR: " << "Invalid Arguments: " << endl << e.error().c_str() << endl;
return 1;
}
hr = srcDataSource.OpenFromFileName(srcUdl); //OpenFromInitializationString(srcConnString);
if (FAILED(hr))
{
DisplayErrorInfo();
return hr;
}
Page 63
hr = srcSession.Open(srcDataSource);
if (FAILED(hr))
{
DisplayErrorInfo();
return hr;
}
CComPtr<IDBSchemaRowset> spSchemaRowset;
hr = srcSession.m_spOpenRowset->QueryInterface(__uuidof(IDBSchemaRowset), (void**)&spSchemaRowset);
if (FAILED(hr))
{
cerr << "** ERROR: QueryInterface(IDBSchemaRowset) returned " << hex << hr << endl;
return hr;
}
VARIANT vNoRestriction;
vNoRestriction.vt = VT_EMPTY;
VARIANT vTableSchemaRestriction;
vTableSchemaRestriction.vt = VT_EMPTY;
if (bstrSchema.length() > 0)
{
vTableSchemaRestriction.vt = VT_BSTR;
vTableSchemaRestriction.bstrVal = SysAllocString(bstrSchema.GetBSTR());
}
VARIANT vIndexNameRestriction;
vIndexNameRestriction.vt = VT_EMPTY;
if (bstrIndex.length() > 0)
{
vIndexNameRestriction.vt = VT_BSTR;
vIndexNameRestriction.bstrVal = SysAllocString(bstrIndex.GetBSTR());
}
VARIANT vTableNameRestriction;
vTableNameRestriction.vt = VT_EMPTY;
if (bstrTable.length() > 0)
{
vTableNameRestriction.vt = VT_BSTR;
vTableNameRestriction.bstrVal = SysAllocString(bstrTable.GetBSTR());
}
hr = pRS.Bind();
hr = pRS.MoveFirst();
MapIndexes::iterator it = mapIndexes.find(indexName);
CIndexDesc& index = (it != mapIndexes.end()) ? it->second : mapIndexes.insert(PairIndexes(indexName,
CIndexDesc(tableName, primaryKey, unique, clustered))).first->second;
index.AddColumn(columnName);
hr = pRS.MoveNext();
}
Page 64
pRS.Close();
cout << " Indexes loaded count: " << mapIndexes.size() << endl;
hr = dstDataSource.OpenFromFileName(dstUdl); //OpenFromInitializationString(dstConnString);
if (FAILED(hr))
{
DisplayErrorInfo();
return hr;
}
hr = dstSession.Open(dstDataSource);
if (FAILED(hr))
{
DisplayErrorInfo();
return hr;
}
CComPtr<IIndexDefinition> spIndexDefinition;
hr = dstSession.m_spOpenRowset->QueryInterface(__uuidof(IIndexDefinition), (void**)&spIndexDefinition);
if (FAILED(hr))
{
cerr << "** ERROR: QueryInterface(IIndexDefinition) failed hr=" << hr << endl;
return hr;
}
DBID TableName;
DBID IndexName;
TableName.eKind = DBKIND_NAME;
TableName.uName.pwszName = (LPOLESTR) index.GetTableName();
IndexName.eKind = DBKIND_NAME;
IndexName.uName.pwszName = (LPOLESTR) it->first.c_str();
DBPROP indexdbprop[4];
DBPROPSET indexdbpropset[1];
DBINDEXCOLUMNDESC* rgIndexColumnDescs = (DBINDEXCOLUMNDESC*)_alloca(lColumns.size() *
sizeof(DBINDEXCOLUMNDESC));
DBID* dbidColumns = (DBID*)_alloca(lColumns.size() * sizeof(DBID));
indexdbprop[1].dwPropertyID = DBPROP_INDEX_PRIMARYKEY;
indexdbprop[1].dwOptions = DBPROPOPTIONS_REQUIRED;
indexdbprop[1].vValue.vt = VT_BOOL;
indexdbprop[1].vValue.lVal = index.GetPrimary() ? VARIANT_TRUE : VARIANT_FALSE;
indexdbprop[1].colid = DB_NULLID;
indexdbprop[2].dwPropertyID = DBPROP_INDEX_CLUSTERED;
indexdbprop[2].dwOptions = DBPROPOPTIONS_REQUIRED;
indexdbprop[2].vValue.vt = VT_BOOL;
indexdbprop[2].vValue.lVal = index.GetClustered() ? VARIANT_TRUE : VARIANT_FALSE;
indexdbprop[2].colid = DB_NULLID;
indexdbprop[3].dwPropertyID = DBPROP_INDEX_UNIQUE;
indexdbprop[3].dwOptions = DBPROPOPTIONS_REQUIRED;
indexdbprop[3].vValue.vt = VT_BOOL;
indexdbprop[3].vValue.lVal = index.GetUnique() ? VARIANT_TRUE : VARIANT_FALSE;
indexdbprop[3].colid = DB_NULLID;
Page 65
for (unsigned i=0; i < lColumns.size(); i++)
{
rgIndexColumnDescs[i].eIndexColOrder = DBINDEX_COL_ORDER_ASC;
rgIndexColumnDescs[i].pColumnID = &dbidColumns[i];
wcout << L" Table: " << TableName.uName.pwszName << L"\t Index: " << IndexName.uName.pwszName << endl;
if (FAILED(hr))
{
DisplayErrorInfo();
if (!bIgnoreAllErrors)
{
cerr << "Terminate the indexes creation process? Enter 'Y' to terminate, " << endl
<< " 'N' to continue, 'I' to ignore all further errors [Y]: ";
string sInput;
std::getline(cin, sInput, '\n');
if (sInput.length() == 0)
break;
CoUninitialize();
cout << "Successfully created " << nSuccess << " indexes. Not being able to create: " << mapIndexes.size() - nSuccess
<< "." << endl;
return 0;
}
Page 66
5.2 DropIndex
Purpose of the DropIndex utility is deleting indexes in DB. Common use case: it can be used to undo changes made by
CopyIndex utility.
USAGE:
Where:
-c, --confirmation
Ask confirmation before dropping an index. Recommended.
--, --ignore_rest
Ignores the rest of the labeled arguments following this flag.
-v, --version
Displays version information and exits.
-h, --help
Displays usage information and exits.
void DisplayErrorInfo()
{
CDBErrorInfo errors;
ULONG errorCount;
HRESULT hr = errors.GetErrorRecords(&errorCount);
if (FAILED(hr))
{
cerr << "** ERROR: hr = " << hex << hr << endl;
return;
Page 67
}
struct CIndexStruc
{
CIndexStruc(wstring i_sTable, wstring i_sIndex) :
sTable(i_sTable), sIndex(i_sIndex)
{}
wstring sTable;
wstring sIndex;
};
TCHAR filename[MAX_PATH];
GetModuleFileName(NULL, filename, MAX_PATH);
VersionInfo verInfo(filename);
try
{
CmdLine cmdline(verInfo.FileDescription(), ' ', verInfo.productVersion_str());
cmdline.parse(argc, argv);
aUdl = udlFileArg.getValue().c_str();
bstrSchema = schemaArg.getValue().c_str();
bstrIndex = indexArg.getValue().c_str();
bstrTable = tableArg.getValue().c_str();
}
catch (ArgException &e)
{
cerr << endl << "** ERROR: " << "Invalid Arguments: " << endl << e.error().c_str() << endl;
return 1;
}
CDataSource dataSource;
CSession session;
hr = dataSource.OpenFromFileName(aUdl);
if (FAILED(hr))
{
DisplayErrorInfo();
return hr;
}
hr = session.Open(dataSource);
if (FAILED(hr))
{
DisplayErrorInfo();
return hr;
Page 68
}
CComPtr<IDBSchemaRowset> spSchemaRowset;
hr = session.m_spOpenRowset->QueryInterface(__uuidof(IDBSchemaRowset), (void**)&spSchemaRowset);
if (FAILED(hr))
{
cerr << "** ERROR: QueryInterface(IDBSchemaRowset) returned " << hex << hr << endl;
return hr;
}
VARIANT vNoRestriction;
vNoRestriction.vt = VT_EMPTY;
VARIANT vTableSchemaRestriction;
vTableSchemaRestriction.vt = VT_EMPTY;
if (bstrSchema.length() > 0)
{
vTableSchemaRestriction.vt = VT_BSTR;
vTableSchemaRestriction.bstrVal = SysAllocString(bstrSchema.GetBSTR());
}
VARIANT vIndexNameRestriction;
vIndexNameRestriction.vt = VT_EMPTY;
if (bstrIndex.length() > 0)
{
vIndexNameRestriction.vt = VT_BSTR;
vIndexNameRestriction.bstrVal = SysAllocString(bstrIndex.GetBSTR());
}
VARIANT vTableNameRestriction;
vTableNameRestriction.vt = VT_EMPTY;
if (bstrTable.length() > 0)
{
vTableNameRestriction.vt = VT_BSTR;
vTableNameRestriction.bstrVal = SysAllocString(bstrTable.GetBSTR());
}
hr = pRS.Bind();
hr = pRS.MoveFirst();
lstIndexes.push_back(CIndexStruc(tableName, indexName));
hr = pRS.MoveNext();
}
pRS.Close();
cout << " Indexes found: " << lstIndexes.size() << endl;
CComPtr<IIndexDefinition> spIndexDefinition;
hr = session.m_spOpenRowset->QueryInterface(__uuidof(IIndexDefinition), (void**)&spIndexDefinition);
if (FAILED(hr))
{
cerr << "** ERROR: QueryInterface(IIndexDefinition) failed hr=" << hr << endl;
return hr;
}
Page 69
int nSuccess = 0;
TableName.eKind = DBKIND_NAME;
TableName.uName.pwszName = (LPOLESTR) it->sTable.c_str();
IndexName.eKind = DBKIND_NAME;
IndexName.uName.pwszName = (LPOLESTR) it->sIndex.c_str();
wcout << L" Table: " << TableName.uName.pwszName << L"\t Index: " << IndexName.uName.pwszName << endl;
if (FAILED(hr))
{
DisplayErrorInfo();
if (!bIgnoreAllErrors)
{
cerr << "Terminate the indexes deletion process? Enter 'Y' to terminate, " << endl
<< " 'N' to continue, 'I' to ignore all further errors [Y]: ";
string sInput;
std::getline(cin, sInput, '\n');
if (sInput.length() == 0)
break;
CoUninitialize();
cout << "Successfully dropped " << nSuccess << " indexes. Not being able to drop: " << lstIndexes.size() - nSuccess <<
"." << endl;
return 0;
}
Page 70
5.3 PGNP Profiler (1.3.x and later)
The profiler utility allows collecting SQL statements with performance counters and internal execution trace from the
PGNP provider. Applications can also publish events into the Profiler’s log using pgnp_comment stored procedure. The
SQL trace and counters information can be filtered, stored to an external file, and loaded later. Any application or
service (32- and 64-bit) that uses PGNP provider can be profiled.
Applications/Logs panel contains list of computer hosts ( ), applications ( ) and log files ( ).
Filter panel allows user to enter text criteria for filtering out the SQL trace.
Messages panel display columns with statement time, SQL text, profiler counters, etc. Columns contain following
information:
“AbsTime” and “RelTime” is first column that displays either absolute or relative time. User can click button on the
toolbar to switch to AbsTime or button – to switch to RelTime;
“SQLType” – displays SQL type, i.e.:
Page 71
“ClientSQL” – displays either SQL from user application or generated by the provider;
“Parse”, “Prepare”, “Execute”, “GetRows” – time in milliseconds spent by provider to parse, prepare, execute
statement and to read rows from database server;
“Rows” – number of rows read or affected during execution of the SQL;
“Database”, “User” – database and user name for the connection;
“PID” – process ID of the application that issued the message;
“SessId” – logical OLEDB session ID, it can be used to distinguish between connections made from the same
application;
“CmdId” – logical OLEDB command ID, reserved for future, can be used to distinguish different commands in the same
session;
“CursorMode” – displays “Forward Only” for ADO client cursor or “Can scroll backwards” – for ADO server cursor;
“Application” – application name and PID, i.e. origin of the message;
“CmdType” – statement type, e.g. SELECT, UPDATE, INSERT, DELETE, CREATE xxx, ALTER, SET, SHOW, DROP xxx,
PROCEDURE, INTERNALPROC, START, COMMIT, ROLLBACK, NOTIFY, COPY, etc.
Details panel displays detailed SQL text for the selected in Messages panel messages. For a selected message it can
display one of or both “Client SQL” and “Executed SQL”. “Client SQL” displays the statement text sent by a user
application. “Executed SQL” displays statement sent by PGNP provider to database. “Client SQL” and “Executed SQL” can
be different. Latter displays parameter values, e.g.:
---------- Client SQL ------------
UPDATE tbl SET modified=?, article=? WHERE id=? AND created=?
---------- Executed SQL ---------
update tbl set modified=[DBTYPE_DBTIMESTAMP,20091016
16:00:00.000],article=[DBTYPE_WSTR,”Nexus12”] where id=[DBTYPE_I4,2000] and
created=[DBTYPE_DBTIMESTAMP,20091009 16:00:00.000]
Start profiling an application Select an application in “Application/Logs” panel and click button in the toolbar.
Start profiling all applications on a host Select a host in “Application/Logs” panel and click button in the toolbar.
computer
Stop/pause profiling an application Select an application in “Application/Logs” panel and click button in the toolbar.
Stop/pause profiling all applications on Select a host in “Application/Logs” panel and click button in the toolbar.
a host computer
Remove application from the list An application can be removed from the list only if it terminated, i.e. has following icon: . Click
Clear button ( ) in the toolbar.
Switch from absolute to relative time Click on button-indicator (to switch to relative time) or on (to switch to absolute time).
and back
Page 72
In the Connection Settings dialog enter a remote computer name or an IP address, and (optionally) user name and
password. Then click Test Connection button. If connection test succeeds, the message will also display the number of
applications available for profiling:
The Host name(s) combo-box keeps history of connections, and can be used to quickly choose one of the previous
connections.
Click OK button to open connection to the remote host. Then click Capture button in the toolbar on top in order to start
collecting trace. The PGNP Profiler can look like the following:
The list of applications on remote hosts will refresh automatically every 10 seconds, similarly to the list on the local host.
The closed applications will be marked with the “red bar” sign, and the new applications will be appended to the list. The
Page 73
list can be refreshed manually by right-clicking mouse on the remote host item, and selecting Refresh menu item, or by
pressing F5.
Note: The PGNP Profiler copies itself to and runs on remote host as Windows service in order to obtain list of applications available.
When the Profiler closes, it performs cleanup. However, if physical connection broke, or some other irregular termination occurred,
manual cleanup might be needed on the remote host computer. Use the following VB script for the cleanup:
wscript.echo "Done!"
There are several preconfigured filters available by right mouse click in the Filter panel:
“ClientSQL Like…” – display SQL messages according to the regular expression, e.g.
clientsql ilike ‘select(.)+’
“Hide System” – hide any “system”, i.e. the provider generated messages, i.e.
SQLType <> SYSTEM
“ExecuteTime > 1ms” – display statements with execution time over 1 millisecond, i.e.
execute > 1.0
“Schema Alterations” – display only schema alteration messages such as DROP TABLE tbl, i.e.
(ClientSQL ilike 'Alter(.)+' || ClientSQL ilike 'Create(.)+' || ClientSQL ilike 'Drop(.)+')
&& SQLType != ERROR
“Stored Procedures and Notifications” – display only stored procedures calls and notifications sent and received, i.e
CMDType == PROCEDURE || CMDType == INTERNALPROC || CMDType == NOTIFY
Operator Description
Page 74
+ Add variables or numeric constants
!= Not equal
= Equal
== Equal
! Logical NOT
|| Logical OR
Like/ILike operators are based on boost regular expressions evaluation engine. For more details read article:
http://www.boost.org/doc/libs/1_40_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html (“Perl Regular
Expression Syntax”).
Variable Constant
SQLType USER
SYSTEM
NOTIFY
ERROR
COLUMNS_SCHEMA
INDEXES_SCHEMA
TABLES_SCHEMA
CATALOGS_SCHEMA
FOREIGN_KEYS_SCHEMA
PRIMARY_KEYS_SCHEMA
PROCEDURE_COLUMNS_SCHEMA
PROCEDURE_PARAMETERS_SCHEMA
PROCEDURES_SCHEMA
CMDType SELECT
INSERT
Page 75
UPDATE
DELETE
CREATE DATABASE
CREATE TABLE
CREATE VIEW
CREATE INDEX
CREATE FUNCTION
ALTER
SET
SHOW
DROP DATABASE
DROP TABLE
DROP VIEW
DROP INDEX
DROP FUNCTION
PROCEDURE
INTERNALPROC
START TRANSACTION
COMMIT
ROLLBACK
NOTIFY
COPY
4 Integer E Number of errors. This number is only for convenience of displaying PGL file in
viewer. It is for avoiding calculation of errors count.
Messages and errors in format described in separate tables below. The messages
and errors are always 4-byte aligned by zeroes appended to the end. The array of
sizes contains sizes including the alignment.
>4 Logger ID to Name value pairs. Logger ID is 4-byte integer used in messages and
error to resolve into Logger Name (usually Process name). The list can have one or
more pairs. Logger Name ends with ‘\0’.
Page 76
1 0 (TRC_NONE) Trace type
1 (TRC_CLIENTSQL)
2 (TRC_SYSTEMSQL)
3 (TRC_NOTIFIES)
4 (TRC_ERROR)
5 (TRC_SCHEMA_COLUMNS)
6 (TRC_SCHEMA_INDEXES)
7 (TRC_SCHEMA_TABLES)
8 (TRC_SCHEMA_CATALOGS)
9 (TRC_SCHEMA_FOREIGN_KEYS)
10 (TRC_SCHEMA_PRIMARY_KEYS)
11 (TRC_SCHEMA_PROCEDURE_COLUMNS)
12 (TRC_SCHEMA_PROCEDURE_PARAMETERS)
13 (TRC_SCHEMA_PROCEDURES)
14 (TRC_SYS_SCHEMA)
15 (TRC_USER_SCHEMA)
16 (TRC_COMMENT)
1 (QT_SELECT)
2 (QT_INSERT)
3 (QT_UPDATE)
4 (QT_DELETE)
5 (QT_CREATE_DATABASE)
6 (QT_CREATE_TABLE)
7 (QT_CREATE_VIEW)
8 (QT_CREATE_INDEX)
9 (QT_CREATE_FUNCTION)
Page 77
10 (QT_ALTER)
11 (QT_SET)
12 (QT_SHOW)
13 (QT_DROP_DATABASE)
14 (QT_DROP_TABLE)
15 (QT_DROP_VIEW)
16 (QT_DROP_INDEX)
17 (QT_DROP_FUNCTION)
18 (QT_PROCEDURE)
19 (QT_INTERNAL_PROC)
20 (QT_START_TRANS)
21 (QT_COMMIT)
22 (QT_ROLLBACK)
23 (QT_NOTIFY)
24 (QT_COPY)
1 (CANSCROLLBACKWARDS)
2 (VIRTUAL)
2 Session ID
2 Command ID
Page 78
4+len Client SQL length and text
2 Session ID
2 Command ID
Key Type
ConnectToHostEnabled DWORD When key exists and set to 1, UI for connecting to remote hosts enabled.
MaxLogFileSize String Contains abbreviated string with maximum size of the .pgl file (current trace).
When the maximum size is reached the current file is closed, and new file is created
with the latest timestamp added to the name. Examples: "1K" -> 1000, "360M" ->
360'000'000, "2.6G" -> 2'000'000'000, "3T" -> 3'000'000'000'000, "0" -> 0 (infinite
size). When missing key or empty value, then maximum size is 2^30. The size
cannot be set smaller than 16777216.
Page 79
5.4 PGNPUpdate (1.4.x and later)
The purpose of PGNPUpdate application is help users to automate the product activation and updates. It may function
in either one of the two modes that are automatically determined on the application startup.
PGNPUpdate launches in Normal mode when the product is activated and is fully functional. It launches in Activation
mode when the product requires activation.
The updates list is sorted by the publication date so that newest updates are listed first. User can install a specific update
by clicking on the link, e.g. 1.4.0.2560, or can install the latest available update by just clicking on the Next button. Click
“Yes” in the confirmation box:
Page 80
Then the update progress and the completion result are shown:
After user entered Product Key and clicked Next button, the Activation Request screen will be shown:
Page 81
E-mail the request to the specified address, and restart the application in order to finish the manual activation process.
After received the Activation Response in an e-mail, enter it on the following page:
Page 82
system error occurred: Class not registered”, or some other error when opening connection. In order to enable a
restricted user access to the PGNP provider, perform the following steps.
Note: it is highly recommended to backup registry before performing the following steps. Even though the changes
should affect only PGNP provider COM registry, it is still a good practice to make backups in order to be able to restore
system to previous state.
Step 1. Locate name of the restricted user running the SQL Server/SSAS/etc. either in Process Explorer or in Sql Server
Configuration Manager. In figure below, it is “NT Service\MSSQL$SQL2014”:
Step 2. Launch PGNPUpdate utility, and open Options dialog. Click “Add…” button in the Permissions pane:
Step 3. In the Select Users or Groups dialog, enter the user name (or multiple names separated by semicolon), and click
Check Names button. If user name is recognized by the Check, it will be underlined as shown below:
Page 83
Click OK, OK in order to save changes.
Then check if SQL Server/SSAS/etc. can access the PGNP provider after granting the access to the user.
Page 84
Error codes returned by PGNPUpdate application in console mode:
Page 85
6 Appendix B. Handling ISequentialStream in the OLEDB provider
Source data STREAM parameter Hint* (CREATE TABLE) Action (destination UTF8)
* Hint is an optional CREATE STATEMENT that the OLEDB provider uses for handling ISequentialStream. Hint overrides
the provider behavior defined by the STREAM connection string parameter.
7 Appendix C. Samples
The samples use schema defined in samples_schema.sql. Make sure to create the schema by executing the sql
commands before launching samples. The schema can be removed by executing commands from samples_clear.sql.
Samples can be compiled with Visual Studio 2005 or later, and Delphi 7.
7.1 C# Samples
No/Name Description
01_GetRecords.cs This sample demonstrates how programmatically connect to PostgreSQL database and get records from
pgnp_samples.contact table.
02_SingleValue.cs This sample demonstrates getting single value from database. It reads number of contacts with last name
starting with 'S'.
03_InsertUpdateDelete.cs This sample demonstrates creation of a temporary table, and records insertion, updates and deletion.
04_CommandParameters.cs This sample demonstrates passing positional and named parameters to a command.
05_StoredProcedures.cs This sample demonstrates how to call stored procedures returning a single result and multiple results.
06_TwoPhaseCommit.cs This sample demonstrates various scenarios in Two Phase Commit protocol.
Page 86
11_NestedTrans.cs This sample demonstrates how to work with nested transactions in .NET
12_DistribTrans.cs This sample demonstrates how to work with distributed transactions in .NET (TransactionsScope object).
13_SavePoints.cs This sample demonstrates how to control transactions via PostgreSQL SAVE POINTs.
Page 87
7.2 C++ Samples
Name Description
ADOEvents This example demonstrates howto subscribe for ADO connection and recordset events.
OLEDBTemplates This sample demonstrates howto select records from a table and insert data using OLEDB templates; and
-- how to call PostgreSQL function with one parameter and get the returned value using OLEDB templates; and
-- how to call PostgreSQL function returning TABLE (recordset).
Page 88
7.3 Delphi 7 Samples
Name Description
TestGrid This sample demonstrates howto populate grid with records from database.
Page 89
AUS Eastern Standard (UTC+10:00) Canberra, Australia/ACT Sydney AEST
Time Melbourne, Sydney
Australia/Canberra
Australia/LHI Lord_Howe AHST
Australia/Victoria Melbourne AEST
Azerbaijan Standard Time (UTC+04:00) Baku Asia/Baku Baku AZST
Azores Standard Time (UTC-01:00) Azores Atlantic/Azores Azores AZOST
Bahia Standard Time (UTC-03:00) Salvador America/Bahia Bahia BRT
Bangladesh Standard (UTC+06:00) Dhaka Asia/Dacca Dhaka BDT
Time
Asia/Thimbu Thimphu BTT
Belarus Standard Time (UTC+03:00) Minsk Europe/Minsk Minsk MSK
Bougainville Standard (UTC+11:00) Bougainville Island Pacific/Bougainville Bougainville BST
Time
Canada Central Standard (UTC-06:00) Saskatchewan Canada/East- Regina CST
Time Saskatchewan
Canada/Saskatchewan Saskatchewan
Cape Verde Standard (UTC-01:00) Cabo Verde Is. Atlantic/Cape_Verde Cape_Verde CVT
Time
Caucasus Standard Time (UTC+04:00) Yerevan Asia/Yerevan Yerevan AMT
Cen. Australia Standard (UTC+09:30) Adelaide Australia/South Adelaide ACST
Time
Australia/Yancowinna Broken_Hill
Central America Standard (UTC-06:00) Central America America/Belize Belize CST
Time
Central Asia Standard (UTC+06:00) Astana Asia/Astana Tselinigrad ALMT
Time
Central Brazilian Standard (UTC-04:00) Cuiaba America/Cuiaba America/Cuiaba AMT
Time
Central Europe Standard (UTC+01:00) Belgrade, Bratislava, Europe/Belgrade Poland CEST
Time Budapest, Ljubljana, Prague
Central European (UTC+01:00) Sarajevo, Skopje, Europe/Warsaw
Standard Time Warsaw, Zagreb
Central Pacific Standard (UTC+11:00) Solomon Is., New Pacific/Pohnpei Ponape PONT
Time Caledonia
Central Standard Time (UTC-06:00) Central Time (US & America/Indiana/Knox America/Knox_IN CDT
Canada)
Canada/Central Winnipeg
US/Central Chicago
US/Indiana-Starke Indiana/Knox
Central Standard Time (UTC-06:00) Guadalajara, Mexico Mexico/General Mexico_City CDT
(Mexico) City, Monterrey
Chatham Islands Standard (UTC+12:45) Chatham Islands Chatham Chatham CHADT
Time
China Standard Time (UTC+08:00) Beijing, Chongqing, Asia/Shanghai Chongqing CST
Hong Kong, Urumqi
Asia/Shanghai Chungking
Asia/Shanghai Harbin
Asia/Kashgar Urumqi
Page 90
Asia/Macao Macau
Asia/Hongkong HongKong
PRC Asia/Shanghai
Cuba Standard Time (UTC-05:00) Havana Cuba Havana CDT
Dateline Standard Time (UTC-12:00) International Date Dateline Dateline IDL
Line West
E. Africa Standard Time (UTC+03:00) Nairobi Africa/Asmera Asmara EAT
E. Australia Standard (UTC+10:00) Brisbane Australia/Queensland Brisbane AEST
Time
E. Europe Standard Time (UTC+02:00) Chisinau Europe/Paris Paris CEST
E. South America (UTC-03:00) Brasilia Brazil/East Sao_Paulo BRT
Standard Time
Easter Island Standard (UTC-06:00) Easter Island EasterIsland Easter_Island CST
Time
Eastern Standard Time (UTC-05:00) Eastern Time (US & America/Coral_Harbour America/Atikokan EST
Canada)
America/Fort_Wayne Indiana/Indianapolis
America/Indianapolis Indianapolis
America/Louisville Louisville
Canada/Eastern Toronto
US/Eastern New_York
US/Michigan America/Detroit
Eastern Standard Time (UTC-05:00) Chetumal America/Cancun Chetumal EST
(Mexico)
Egypt Standard Time (UTC+02:00) Cairo Africa/Cairo Egypt EEST
Ekaterinburg Standard (UTC+05:00) Ekaterinburg Asia/Yekaterinburg Ekaterinburg YEKT
Time
Fiji Standard Time (UTC+12:00) Fiji Pacific/Fiji Fiji FJST
FLE Standard Time (UTC+02:00) Helsinki, Kyiv, Riga, Europe/Helsinki Helsinki FLET
Sofia, Tallinn, Vilnius
Georgian Standard Time (UTC+04:00) Tbilisi Asia/Tbilisi Tbilisi GET
GMT Standard Time (UTC+00:00) Dublin, Edinburgh, Etc/GMT London GMT
Lisbon, London
Greenland Standard Time (UTC-03:00) Greenland America/Godthab Greenland WGT
Greenwich Standard Time (UTC+00:00) Monrovia, Reykjavik Atlantic/Reykjavik Reykjavik GMT
GTB Standard Time (UTC+02:00) Athens, Bucharest Europe/Athens Athens EEST
Haiti Standard Time (UTC-05:00) Haiti America/Haiti Haiti EST
Hawaiian Standard Time (UTC-10:00) Hawaii Pacific/Honolulu Hawaii HST
India Standard Time (UTC+05:30) Chennai, Kolkata, India/Chennai India IST
Mumbai, New Delhi
Iran Standard Time (UTC+03:30) Tehran Asia/Tehran Iran IRT
Israel Standard Time (UTC+02:00) Jerusalem Asia/Jerusalem Israel IST
Jordan Standard Time (UTC+02:00) Amman Asia/Amman Jordan EEST
Kaliningrad Standard (UTC+02:00) Kaliningrad Europe/Kaliningrad Kaliningrad CET
Time
Kamchatka Standard (UTC+12:00) Petropavlovsk- Asia/Kamchatka Kamchatka PET
Time Kamchatsky - Old
Korea Standard Time (UTC+09:00) Seoul Asia/Seoul Korea KDT
Page 91
Libya Standard Time (UTC+02:00) Tripoli Africa/Tripoli Libya EET
Line Islands Standard (UTC+14:00) Kiritimati Island Pacific/Kiritimati Kiribati LINT
Time
Lord Howe Standard Time (UTC+10:30) Lord Howe Island Australia/Lord_Howe Australia LHDT
Magadan Standard Time (UTC+11:00) Magadan Asia/Magadan Magadan MAGT
Marquesas Standard Time (UTC-09:30) Marquesas Islands Pacific/Marquesas Marquesas MART
Mauritius Standard Time (UTC+04:00) Port Louis Indian/Mauritius Mauritius MUT
Middle East Standard (UTC+02:00) Beirut Asia/Beirut Lebanon EEST
Time
Montevideo Standard (UTC-03:00) Montevideo America/Montevideo Uruguay UYT
Time
Morocco Standard Time (UTC+00:00) Casablanca Africa/Casablanca Morocco WET
Mountain Standard Time (UTC-07:00) Mountain Time (US America/Denver Colorado MST
& Canada)
Mountain Standard Time (UTC-07:00) Chihuahua, La Paz, America/Chihuahua Chihuahua MDT
(Mexico) Mazatlan
Myanmar Standard Time (UTC+06:30) Yangon (Rangoon) Asia/Rangoon Myanmar MMT
N. Central Asia Standard (UTC+06:00) Novosibirsk Asia/Novosibirsk Novosibirsk NOVT
Time
Namibia Standard Time (UTC+01:00) Windhoek Africa/Windhoek Namibia WAT
Nepal Standard Time (UTC+05:45) Kathmandu Asia/Katmandu Nepal NPT
New Zealand Standard (UTC+12:00) Auckland, Pacific/Auckland New Zealand NZST
Time Wellington
Newfoundland Standard (UTC-03:30) Newfoundland America/St_Johns Newfoundland NDT
Time
Norfolk Standard Time (UTC+11:00) Norfolk Island Pacific/Norfolk Norfolk NFT
North Asia East Standard (UTC+08:00) Irkutsk Asia/Irkutsk Irkutsk IRKT
Time
North Asia Standard Time (UTC+07:00) Krasnoyarsk Asia/Krasnoyarsk Krasnoyarsk KRAT
North Korea Standard (UTC+08:30) Pyongyang Asia/Pyongyang North Korea KST
Time
Pacific SA Standard Time (UTC-04:00) Santiago America/Santiago Chile CLT
Pacific Standard Time (UTC-08:00) Pacific Time (US & America/Los_Angeles Los_Angeles PST
Canada)
Pacific Standard Time (UTC-08:00) Baja California America/Tijuana Tijuana PST
(Mexico)
Pakistan Standard Time (UTC+05:00) Islamabad, Karachi Asia/Islamabad Pakistan PKT
Paraguay Standard Time (UTC-04:00) Asuncion America/Asuncion Paraguay PYST
Romance Standard Time (UTC+01:00) Brussels, Europe/Brussels Belgium CEST
Copenhagen, Madrid, Paris
Russia Time Zone 10 (UTC+11:00) Chokurdakh Asia/Srednekolymsk Srednekolymsk SRET
Russia Time Zone 11 (UTC+12:00) Anadyr, Asia/Anadyr Anadyr ANAT
Petropavlovsk-Kamchatsky
Russia Time Zone 3 (UTC+04:00) Izhevsk, Samara Europe/Izhevsk Samara SAMT
Russian Standard Time (UTC+03:00) Moscow, St. Europe/Moscow Moscow MSK
Petersburg, Volgograd
SA Eastern Standard Time (UTC-03:00) Cayenne, Fortaleza America/Cayenne Cayenne GFT
SA Pacific Standard Time (UTC-05:00) Bogota, Lima, Quito, America/Bogota Peru PET
Rio Branco
Page 92
SA Western Standard (UTC-04:00) Georgetown, La Paz, America/La Paz Bolivia BOT
Time Manaus, San Juan
Saint Pierre Standard (UTC-03:00) Saint Pierre and America/Saint Pierre Saint Pierre PMST
Time Miquelon
Sakhalin Standard Time (UTC+11:00) Sakhalin Asia/Sakhalin Sakhalin SAKT
Samoa Standard Time (UTC+13:00) Samoa America/Samoa Samoa SST
SE Asia Standard Time (UTC+07:00) Bangkok, Hanoi, Asia/Bangkok Bangkok ICT
Jakarta
Singapore Standard Time (UTC+08:00) Kuala Lumpur, Asia/Singapore Singapore SGT
Singapore
South Africa Standard (UTC+02:00) Harare, Pretoria Africa/Harare Harare SAST
Time
Sri Lanka Standard Time (UTC+05:30) Sri Asia/Colombo Sri_Lanka SLST
Jayawardenepura
Syria Standard Time (UTC+02:00) Damascus Asia/Damascus Syria EEST
Taipei Standard Time (UTC+08:00) Taipei Asia/Taipei Taiwan CST
Tasmania Standard Time (UTC+10:00) Hobart Hobart Tasmania AEST
Tocantins Standard Time (UTC-03:00) Araguaina America/Tocantins Tocantins BRT
Tokyo Standard Time (UTC+09:00) Osaka, Sapporo, Asia/Tokyo Japan JST
Tokyo
Tomsk Standard Time (UTC+07:00) Tomsk Asia/Tomsk Tomsk ALMT
Tonga Standard Time (UTC+13:00) Nuku'alofa Pacific/Tongatapu Tongatapu TOT
Transbaikal Standard (UTC+09:00) Chita Asia/Atamanovka Chita TST
Time
Turkey Standard Time (UTC+02:00) Istanbul Europe/Istanbul Turkey EEST
Turks And Caicos (UTC-04:00) Turks and Caicos America/Turks_Caicos Cockburn_Town AST
Standard Time
Ulaanbaatar Standard (UTC+08:00) Ulaanbaatar Asia/Ulaanbaatar Mongolia ULAT
Time
US Eastern Standard Time (UTC-05:00) Indiana (East) America/Indiana Indianapolis EDT
US Mountain Standard (UTC-07:00) Arizona America/Phoenix Arizona MST
Time
UTC (UTC) Coordinated Universal Time UTC
UTC+12 (UTC+12:00) Coordinated Universal Time+12 UTCp12
UTC-02 (UTC-02:00) Coordinated Universal Time-02 UTCm2
UTC-08 (UTC-08:00) Coordinated Universal Time-08 UTCm8
UTC-09 (UTC-09:00) Coordinated Universal Time-09 UTCm9
UTC-11 (UTC-11:00) Coordinated Universal Time-11 UTCm11
Venezuela Standard Time (UTC-04:00) Caracas America/Caracas Venezuela VET
Vladivostok Standard (UTC+10:00) Vladivostok Asia/Vladivostok Vladivostok VLAT
Time
W. Australia Standard (UTC+08:00) Perth Australia/Perth Perth AWST
Time
W. Central Africa (UTC+01:00) West Central Africa Africa/Kinshasa Kinshasa WAT
Standard Time
W. Europe Standard Time (UTC+01:00) Amsterdam, Berlin, Europe/Amsterdam Holland CEST
Bern, Rome, Stockholm, Vienna
W. Mongolia Standard (UTC+07:00) Hovd Asia/Hovd Hovd HOVT
Time
Page 93
West Asia Standard Time (UTC+05:00) Ashgabat, Tashkent Asia/Ashgabat Turkmenistan TMT
West Bank Standard Time (UTC+02:00) Gaza, Hebron Asia/Gaza Palestina EEST
West Pacific Standard (UTC+10:00) Guam, Port Asia/Guam Guam CHST
Time Moresby
Yakutsk Standard Time (UTC+09:00) Yakutsk Asia/Yakutsk Yakutsk YAKT
Note: time zones names in the tznames.csv file cannot contain double quote and semicolon characters. Also, lines with no name in first column, or
all empty columns except the first are ignored. PGNProfiler shows messages regarding the tznames.csv loading at Comment Level 2.
The time zones can be selected in the Data Link Properties dialog:
Page 94