Commit 3a7f4f24 authored by Olivier Bertrand's avatar Olivier Bertrand

- Commit merged files from Alexander

added:
  storage/connect/mysql-test/connect/r/odbc_postgresql.result
  storage/connect/mysql-test/connect/t/have_odbc_postgresql.inc
  storage/connect/mysql-test/connect/t/odbc_postgresql.sql
  storage/connect/mysql-test/connect/t/odbc_postgresql.test
modified:
  storage/connect/odbconn.cpp
parents f69980c6 83416c0f
This diff is collapsed.
--disable_query_log
--error 0,ER_UNKNOWN_ERROR
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Sources;
if ($mysql_errno)
{
Skip No ODBC support;
}
if (!`SELECT count(*) FROM t1 WHERE Name='ConnectEnginePostgresql'`)
{
DROP TABLE t1;
Skip Need ODBC data source ConnectEnginePostgresql;
}
SHOW CREATE TABLE t1;
DROP TABLE t1;
--enable_query_log
--
-- The SQL script to create PostgreSQL data for odbc_postgresql.test
--
-- Run this script as a admin user:
-- sudo -u postgres psql < odbc_postgresql.create.sql
DROP DATABASE IF EXISTS mtr;
DROP USER IF EXISTS mtr;
CREATE USER mtr WITH PASSWORD 'mtr';
CREATE DATABASE mtr OWNER=mtr ENCODING='UTF8';
GRANT ALL ON DATABASE mtr TO mtr;
\c mtr
SET role mtr;
CREATE TABLE t1 (a INT NOT NULL);
INSERT INTO t1 VALUES (10),(20),(30);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TABLE t2 (a INT NOT NULL);
INSERT INTO t2 VALUES (40),(50),(60);
CREATE SCHEMA schema1 AUTHORIZATION mtr;
CREATE TABLE schema1.t1 (a CHAR(10) NOT NULL);
INSERT INTO schema1.t1 VALUES ('aaa'),('bbb'),('ccc'),('яяя');
CREATE VIEW schema1.v1 AS SELECT * FROM schema1.t1;
CREATE TABLE schema1.t2 (a CHAR(10) NOT NULL);
INSERT INTO schema1.t2 VALUES ('xxx'),('yyy'),('zzz'),('ÄÖÜ');
--source have_odbc_postgresql.inc
--source include/not_embedded.inc
#
# To configure your system to be able to run this test,
# follow through the following steps:
#
# 1. Install and configure PostgreSQL database to stat on the system startup
#
# 2. Create user, database, schema and tables to be used by mtr:
# sudo -u postgres < odbc_postgresql.sql
#
# 3. Install PostgreSQL ODBC Driver.
# - On CentOS, Fedora:
# sudo yum install postgresql-odbc
# - On Ubuntu, Debian:
# sudo apt-get install odbc-postgresql
#
# 4. Create a data source with the name "ConnectEnginePostgresql"
# - On Windows: use odbcadm.exe
# - On Linux: put these lines into /etc/odbc.ini
#
#[ConnectEnginePostgresql]
#Description=PostgreSQL DSN for ConnectSE
#Driver=PostgreSQL
#Database=mtr
#Servername=localhost
#Port=5432
#
SET NAMES utf8;
--echo #
--echo # Checking CATFUNC=Tables
--echo #
--echo
--echo # All tables in all schemas
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables;
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All tables in all schemas
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='%.%.%';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All tables in all schemas
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='%.%';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All tables in the default schema ("public")
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='%';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All tables "t1" in all schemas
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='%.%.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All tables "t1" in all schemas
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='%.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # Table "t1" in the default schema ("public")
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # Table "t1" in the schema "public"
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='%.public.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # Table "t1" in the schema "schema1"
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='%.schema1.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All tables "t1" in all schemas (Catalog name is ignored by PostgreSQL)
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Tables TABNAME='xxx.%.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo #
--echo # Checking CATFUNC=Columns
--echo #
--echo
#
# For some reasons SQLColumn (unlike SQLTables) include columns of system
# tables from the schemas like "information_schema", "pg_catalog", "pg_toast".
# So we add the "Table_Owner IN ('public','schema1')" clause into some queries.
#
--echo # All columns in the schemas "public" and "schema1"
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Columns;
SELECT * FROM t1 WHERE Table_Owner IN ('public','schema1') ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All columns in the schemas "public" and "schema1"
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Columns TABNAME='%.%.%';
SELECT * FROM t1 WHERE Table_Owner IN ('public','schema1') ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All tables "t1" in all schemas
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Columns TABNAME='%.%.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # Table "t1" in the schema "public"
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Columns TABNAME='%.public.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # Table "t1" in the schema "schema1"
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Columns TABNAME='%.schema1.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo # All tables "t1" in all schemas (Catalog name is ignored by PostgreSQL)
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' CATFUNC=Columns TABNAME='xxx.%.t1';
SELECT * FROM t1 ORDER BY Table_Owner, Table_Name;
DROP TABLE t1;
--echo #
--echo # Checking tables
--echo #
--echo
--echo # Table "t1" in the default schema ("public")
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr';
SHOW CREATE TABLE t1;
SELECT * FROM t1;
CREATE TABLE t2 AS SELECT * FROM t1;
SHOW CREATE TABLE t2;
SELECT * FROM t2;
DROP TABLE t2;
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
--echo # Table "t1" in the schema "public"
CREATE TABLE t1 ENGINE=CONNECT TABNAME='public.t1' TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr';
SHOW CREATE TABLE t1;
SELECT * FROM t1;
DROP TABLE t1;
--echo # Table "t1" in the schema "schema1"
CREATE TABLE t1 ENGINE=CONNECT TABNAME='schema1.t1' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr';
SHOW CREATE TABLE t1;
SELECT * FROM t1;
CREATE TABLE t2 AS SELECT * FROM t1;
SHOW CREATE TABLE t2;
SELECT * FROM t2;
DROP TABLE t2;
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
--echo # View "v1" in the schema "schema1"
CREATE TABLE t1 ENGINE=CONNECT TABNAME='schema1.v1' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr';
SHOW CREATE TABLE t1;
SELECT * FROM t1;
CREATE TABLE t2 AS SELECT * FROM t1;
SHOW CREATE TABLE t2;
SELECT * FROM t2;
DROP TABLE t2;
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
--echo # Table "t2" in the schema "schema1"
CREATE TABLE t1 ENGINE=CONNECT TABNAME='schema1.t2' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr';
SHOW CREATE TABLE t1;
SELECT * FROM t1;
CREATE TABLE t2 AS SELECT * FROM t1;
SHOW CREATE TABLE t2;
SELECT * FROM t2;
DROP TABLE t2;
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
...@@ -1986,6 +1986,87 @@ bool ODBConn::GetDrivers(PQRYRES qrp) ...@@ -1986,6 +1986,87 @@ bool ODBConn::GetDrivers(PQRYRES qrp)
return rv; return rv;
} // end of GetDrivers } // end of GetDrivers
/**
A helper class to split an optionally qualified table name into components.
These formats are understood:
"CatalogName.SchemaName.TableName"
"SchemaName.TableName"
"TableName"
*/
class SQLQualifiedName
{
static const uint max_parts= 3; /* Catalog.Schema.Table */
MYSQL_LEX_STRING m_part[max_parts];
char m_buf[512];
void lex_string_set(MYSQL_LEX_STRING *S, char *str, size_t length)
{
S->str= str;
S->length= length;
}
void lex_string_shorten_down(MYSQL_LEX_STRING *S, size_t offs)
{
DBUG_ASSERT(offs <= S->length);
S->str+= offs;
S->length-= offs;
}
/*
Find the rightmost '.' delimiter and return the length
of the qualifier, including the rightmost '.' delimier.
For example, for the string {"a.b.c",5} it will return 4,
which is the length of the qualifier "a.b."
*/
size_t lex_string_find_qualifier(MYSQL_LEX_STRING *S)
{
size_t i;
for (i= S->length; i > 0; i--)
{
if (S->str[i - 1] == '.')
{
S->str[i - 1]= '\0';
return i;
}
}
return 0;
}
public:
/*
Initialize to the given optionally qualified name.
NULL pointer in "name" is supported.
*/
SQLQualifiedName(const char *name)
{
size_t len, i= 0;
if (!name)
goto ret;
/* Initialize the first (rightmost) part */
lex_string_set(&m_part[0], m_buf,
strmake(m_buf, name, sizeof(m_buf) - 1) - m_buf);
/* Initialize the other parts, if exist. */
for (i= 1; i < max_parts; i++)
{
if (!(len= lex_string_find_qualifier(&m_part[i - 1])))
break;
lex_string_set(&m_part[i], m_part[i - 1].str, len - 1);
lex_string_shorten_down(&m_part[i - 1], len);
}
ret:
/* Initialize the remaining parts */
for ( ; i < max_parts; i++)
lex_string_set(&m_part[i], NULL, 0);
}
SQLCHAR *ptr(uint i)
{
DBUG_ASSERT(i < max_parts);
return (SQLCHAR *) (m_part[i].length ? m_part[i].str : NULL);
}
size_t length(uint i)
{
DBUG_ASSERT(i < max_parts);
return m_part[i].length;
}
};
/***********************************************************************/ /***********************************************************************/
/* Allocate recset and call SQLTables, SQLColumns or SQLPrimaryKeys. */ /* Allocate recset and call SQLTables, SQLColumns or SQLPrimaryKeys. */
/***********************************************************************/ /***********************************************************************/
...@@ -2048,29 +2129,38 @@ int ODBConn::GetCatInfo(CATPARM *cap) ...@@ -2048,29 +2129,38 @@ int ODBConn::GetCatInfo(CATPARM *cap)
} else } else
ThrowDBX("0-sized result"); ThrowDBX("0-sized result");
SQLQualifiedName name((const char *) cap->Tab);
// Now do call the proper ODBC API // Now do call the proper ODBC API
switch (cap->Id) { switch (cap->Id) {
case CAT_TAB: case CAT_TAB:
// rc = SQLSetStmtAttr(hstmt, SQL_ATTR_METADATA_ID, // rc = SQLSetStmtAttr(hstmt, SQL_ATTR_METADATA_ID,
// (SQLPOINTER)false, 0); // (SQLPOINTER)false, 0);
fnc = "SQLTables"; fnc = "SQLTables";
rc = SQLTables(hstmt, NULL, 0, NULL, 0, cap->Tab, SQL_NTS, rc = SQLTables(hstmt, name.ptr(2), name.length(2),
cap->Pat, SQL_NTS); name.ptr(1), name.length(1),
name.ptr(0), name.length(0),
cap->Pat, SQL_NTS);
break; break;
case CAT_COL: case CAT_COL:
// rc = SQLSetStmtAttr(hstmt, SQL_ATTR_METADATA_ID, // rc = SQLSetStmtAttr(hstmt, SQL_ATTR_METADATA_ID,
// (SQLPOINTER)true, 0); // (SQLPOINTER)true, 0);
fnc = "SQLColumns"; fnc = "SQLColumns";
rc = SQLColumns(hstmt, NULL, 0, NULL, 0, cap->Tab, SQL_NTS, rc = SQLColumns(hstmt, name.ptr(2), name.length(2),
cap->Pat, SQL_NTS); name.ptr(1), name.length(1),
name.ptr(0), name.length(0),
cap->Pat, SQL_NTS);
break; break;
case CAT_KEY: case CAT_KEY:
fnc = "SQLPrimaryKeys"; fnc = "SQLPrimaryKeys";
rc = SQLPrimaryKeys(hstmt, NULL, 0, NULL, 0, cap->Tab, SQL_NTS); rc = SQLPrimaryKeys(hstmt, name.ptr(2), name.length(2),
name.ptr(1), name.length(1),
name.ptr(0), name.length(0));
break; break;
case CAT_STAT: case CAT_STAT:
fnc = "SQLStatistics"; fnc = "SQLStatistics";
rc = SQLStatistics(hstmt, NULL, 0, NULL, 0, cap->Tab, SQL_NTS, rc = SQLStatistics(hstmt, name.ptr(2), name.length(2),
name.ptr(1), name.length(1),
name.ptr(0), name.length(0),
cap->Unique, cap->Accuracy); cap->Unique, cap->Accuracy);
break; break;
case CAT_SPC: case CAT_SPC:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment