~ubuntu-branches/ubuntu/saucy/psqlodbc/saucy-proposed

« back to all changes in this revision

Viewing changes to info.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Berg
  • Date: 2011-04-05 14:48:23 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20110405144823-n77supsa1hjj0ik6
Tags: 1:09.00.0200-1
* New upstream release.
* Fix installing {A,W}/usr/lib/odbc.  Closes: #618210.
* Convert to 3.0 (quilt).
* Remove psqlodbc-580878.diff: implemented upstream.
* Remove psqlodbc-585476.diff: was caused by #519006 which is now closed.
* Update description, suggested by Martin Eberhard Schauer.
  Closes: #565611.
* New maintainer.  Closes: #472818.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#include "multibyte.h"
41
41
#include "catfunc.h"
42
42
 
43
 
 
44
43
/*      Trigger related stuff for SQLForeign Keys */
45
44
#define TRIGGER_SHIFT 3
46
45
#define TRIGGER_MASK   0x03
70
69
        char            tmp[MAX_INFO_STRING];
71
70
        SQLULEN                 len = 0,
72
71
                                value = 0;
73
 
        RETCODE         result;
 
72
        RETCODE         result = SQL_ERROR;
74
73
        char            odbcver[16];
75
74
        int             i_odbcver;
76
75
 
770
769
                default:
771
770
                        /* unrecognized key */
772
771
                        CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Unrecognized key passed to PGAPI_GetInfo.", NULL);
773
 
                        return SQL_ERROR;
 
772
                        goto cleanup;
774
773
        }
775
774
 
776
775
        result = SQL_SUCCESS;
838
837
        CSTR func = "PGAPI_GetTypeInfo";
839
838
        StatementClass *stmt = (StatementClass *) hstmt;
840
839
        ConnectionClass *conn;
841
 
        QResultClass    *res;
 
840
        QResultClass    *res = NULL;
842
841
        TupleField      *tuple;
843
842
        int                     i, result_cols;
844
843
 
894
893
 
895
894
        for (i = 0, sqlType = sqlTypes[0]; sqlType; sqlType = sqlTypes[++i])
896
895
        {
897
 
                pgType = sqltype_to_pgtype(stmt, sqlType);
 
896
                pgType = sqltype_to_pgtype(conn, sqlType);
898
897
 
899
898
if (sqlType == SQL_LONGVARBINARY)
900
899
{
919
918
                        }
920
919
                        for (cnt = 0; cnt < pgtcount; cnt ++)
921
920
                        {
922
 
                                tuple = QR_AddNew(res);
 
921
                                if (tuple = QR_AddNew(res), NULL == tuple)
 
922
                                {
 
923
                                        result = SQL_ERROR;
 
924
                                        SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't QR_AddNew.", func);
 
925
                                        goto cleanup;
 
926
                                }
923
927
 
924
928
                                /* These values can't be NULL */
925
929
                                if (aunq_match == cnt)
926
930
                                {
927
 
                                        set_tuplefield_string(&tuple[0], pgtype_to_name(stmt, pgType, TRUE));
 
931
                                        set_tuplefield_string(&tuple[0], pgtype_to_name(stmt, pgType, PG_UNSPECIFIED, TRUE));
928
932
                                        set_tuplefield_int2(&tuple[6], SQL_NO_NULLS);
929
933
inolog("serial in\n");
930
934
                                }
931
935
                                else
932
936
                                {
933
 
                                        set_tuplefield_string(&tuple[0], pgtype_to_name(stmt, pgType, FALSE));
934
 
                                        set_tuplefield_int2(&tuple[6], pgtype_nullable(stmt, pgType));
 
937
                                        set_tuplefield_string(&tuple[0], pgtype_to_name(stmt, pgType, PG_UNSPECIFIED, FALSE));
 
938
                                        set_tuplefield_int2(&tuple[6], pgtype_nullable(conn, pgType));
935
939
                                }
936
940
                                set_tuplefield_int2(&tuple[1], (Int2) sqlType);
937
 
                                set_tuplefield_int2(&tuple[7], pgtype_case_sensitive(stmt, pgType));
938
 
                                set_tuplefield_int2(&tuple[8], pgtype_searchable(stmt, pgType));
939
 
                                set_tuplefield_int2(&tuple[10], pgtype_money(stmt, pgType));
 
941
                                set_tuplefield_int2(&tuple[7], pgtype_case_sensitive(conn, pgType));
 
942
                                set_tuplefield_int2(&tuple[8], pgtype_searchable(conn, pgType));
 
943
                                set_tuplefield_int2(&tuple[10], pgtype_money(conn, pgType));
940
944
 
941
945
                        /*
942
946
                         * Localized data-source dependent data type name (always
945
949
                                set_tuplefield_null(&tuple[12]);
946
950
 
947
951
                                /* These values can be NULL */
948
 
                                set_nullfield_int4(&tuple[2], pgtype_column_size(stmt, pgType, PG_STATIC, PG_STATIC));
949
 
                                set_nullfield_string(&tuple[3], pgtype_literal_prefix(stmt, pgType));
950
 
                                set_nullfield_string(&tuple[4], pgtype_literal_suffix(stmt, pgType));
951
 
                                set_nullfield_string(&tuple[5], pgtype_create_params(stmt, pgType));
 
952
                                set_nullfield_int4(&tuple[2], pgtype_column_size(stmt, pgType, PG_STATIC, UNKNOWNS_AS_DEFAULT));
 
953
                                set_nullfield_string(&tuple[3], pgtype_literal_prefix(conn, pgType));
 
954
                                set_nullfield_string(&tuple[4], pgtype_literal_suffix(conn, pgType));
 
955
                                set_nullfield_string(&tuple[5], pgtype_create_params(conn, pgType));
952
956
                                if (1 < pgtcount)
953
957
                                        set_tuplefield_int2(&tuple[9], SQL_TRUE);
954
958
                                else
955
 
                                        set_nullfield_int2(&tuple[9], pgtype_unsigned(stmt, pgType));
 
959
                                        set_nullfield_int2(&tuple[9], pgtype_unsigned(conn, pgType));
956
960
                                if (aunq_match == cnt)
957
961
                                        set_tuplefield_int2(&tuple[11], SQL_TRUE);
958
962
                                else
959
 
                                        set_nullfield_int2(&tuple[11], pgtype_auto_increment(stmt, pgType));
960
 
                                set_nullfield_int2(&tuple[13], pgtype_min_decimal_digits(stmt, pgType));
961
 
                                set_nullfield_int2(&tuple[14], pgtype_max_decimal_digits(stmt, pgType));
 
963
                                        set_nullfield_int2(&tuple[11], pgtype_auto_increment(conn, pgType));
 
964
                                set_nullfield_int2(&tuple[13], pgtype_min_decimal_digits(conn, pgType));
 
965
                                set_nullfield_int2(&tuple[14], pgtype_max_decimal_digits(conn, pgType));
962
966
#if (ODBCVER >=0x0300)
963
967
                                set_nullfield_int2(&tuple[15], pgtype_to_sqldesctype(stmt, pgType, PG_STATIC));
964
 
                                set_nullfield_int2(&tuple[16], pgtype_to_datetime_sub(stmt, pgType));
965
 
                                set_nullfield_int4(&tuple[17], pgtype_radix(stmt, pgType));
 
968
                                set_nullfield_int2(&tuple[16], pgtype_to_datetime_sub(stmt, pgType, PG_UNSPECIFIED));
 
969
                                set_nullfield_int4(&tuple[17], pgtype_radix(conn, pgType));
966
970
                                set_nullfield_int4(&tuple[18], 0);
967
971
#endif /* ODBCVER */
968
972
                        }
977
981
         */
978
982
        stmt->status = STMT_FINISHED;
979
983
        stmt->currTuple = -1;
980
 
        SC_set_rowset_start(stmt, -1, FALSE);
 
984
        if (SQL_SUCCEEDED(result))
 
985
                SC_set_rowset_start(stmt, -1, FALSE);
 
986
        else
 
987
                SC_set_Result(stmt, NULL);
981
988
        SC_set_current_col(stmt, -1);
982
989
 
983
990
        if (stmt->internal)
1479
1486
        return (addE ? like_op_ext : like_op_sp);
1480
1487
}
1481
1488
 
 
1489
/*
 
1490
 *      If specified schema name == user_name and the current schema is
 
1491
 *      'public', allowed to use the 'public' schema.
 
1492
 */
 
1493
static BOOL
 
1494
allow_public_schema(ConnectionClass *conn, const char *szSchemaName, SQLSMALLINT cbSchemaName)
 
1495
{
 
1496
        const char *user = CC_get_username(conn);
 
1497
        size_t  userlen = strlen(user);
 
1498
 
 
1499
        if (NULL == szSchemaName)
 
1500
                return FALSE;
 
1501
 
 
1502
        if (SQL_NTS == cbSchemaName)
 
1503
                cbSchemaName = strlen(szSchemaName);
 
1504
 
 
1505
        return (cbSchemaName == (SQLSMALLINT) userlen &&
 
1506
                strnicmp(szSchemaName, user, userlen) == 0 &&
 
1507
                stricmp(CC_get_current_schema(conn), pubstr) == 0);
 
1508
}
 
1509
 
1482
1510
RETCODE         SQL_API
1483
1511
PGAPI_Tables(
1484
1512
                         HSTMT hstmt,
1593
1621
 
1594
1622
        tables_query[0] = '\0';
1595
1623
        if (list_cat)
1596
 
                strncpy(tables_query, "select NULL, NULL, NULL", sizeof(tables_query));
 
1624
                strncpy_null(tables_query, "select NULL, NULL, NULL", sizeof(tables_query));
1597
1625
        else if (list_table_types)
1598
 
                strncpy(tables_query, "select NULL, NULL, relkind from (select 'r' as relkind union select 'v') as a", sizeof(tables_query));
 
1626
                strncpy_null(tables_query, "select NULL, NULL, relkind from (select 'r' as relkind union select 'v') as a", sizeof(tables_query));
1599
1627
        else if (list_schemas)
1600
1628
        {
1601
1629
                if (conn->schema_support)
1602
 
                        strncpy(tables_query, "select NULL, nspname, NULL"
 
1630
                        strncpy_null(tables_query, "select NULL, nspname, NULL"
1603
1631
                        " from pg_catalog.pg_namespace n where true", sizeof(tables_query));
1604
1632
                else
1605
 
                        strncpy(tables_query, "select NULL, NULL as nspname, NULL", sizeof(tables_query));
 
1633
                        strncpy_null(tables_query, "select NULL, NULL as nspname, NULL", sizeof(tables_query));
1606
1634
        }
1607
1635
        else if (conn->schema_support)
1608
1636
        {
1759
1787
            (res = SC_get_Result(tbl_stmt)) &&
1760
1788
            0 == QR_get_num_total_tuples(res))
1761
1789
        {
1762
 
                const char *user = CC_get_username(conn);
1763
 
 
1764
 
                /*
1765
 
                 * If specified schema name == user_name and
1766
 
                 * the current schema is 'public',
1767
 
                 * retry the 'public' schema.
1768
 
                 */
1769
 
                if (szSchemaName &&
1770
 
                    (cbSchemaName == SQL_NTS ||
1771
 
                     cbSchemaName == (SQLSMALLINT) strlen(user)) &&
1772
 
                    strnicmp(szSchemaName, user, strlen(user)) == 0 &&
1773
 
                    stricmp(CC_get_current_schema(conn), pubstr) == 0)
 
1790
                if (allow_public_schema(conn, szSchemaName, cbSchemaName))
1774
1791
                {
1775
1792
                        szSchemaName = pubstr;
1776
1793
                        cbSchemaName = SQL_NTS;
1916
1933
                        if (list_some)
1917
1934
                                set_tuplefield_null(&tuple[TABLES_TABLE_NAME]);
1918
1935
                        else
1919
 
                                set_nullfield_string(&tuple[TABLES_TABLE_NAME], table_name);
 
1936
                                set_tuplefield_string(&tuple[TABLES_TABLE_NAME], table_name);
1920
1937
                        if (list_table_types || !list_some)
1921
1938
                                set_tuplefield_string(&tuple[TABLES_TABLE_TYPE], systable ? "SYSTEM TABLE" : (view ? "VIEW" : "TABLE"));
1922
1939
                        else
1991
2008
                                field_name[MAX_INFO_STRING],
1992
2009
                                field_type_name[MAX_INFO_STRING];
1993
2010
        Int2            field_number, sqltype, concise_type,
1994
 
                                result_cols,
1995
 
                                decimal_digits;
1996
 
        Int4            field_type,
1997
 
                                the_type,
1998
 
                                field_length,
1999
 
                                mod_length,
2000
 
                                column_size,
2001
 
                                ordinal;
 
2011
                                result_cols;
 
2012
        Int4            mod_length,
 
2013
                                ordinal,
 
2014
                                typmod;
 
2015
        OID             field_type, the_type, greloid, basetype;
 
2016
#ifdef  USE_OLD_IMPL
 
2017
        Int2            decimal_digits;
 
2018
        Int4            field_length, column_size;
2002
2019
        char            useStaticPrecision, useStaticScale;
 
2020
#endif /* USE_OLD_IMPL */
2003
2021
        char            not_null[MAX_INFO_STRING],
2004
2022
                                relhasrules[MAX_INFO_STRING], relkind[8];
2005
2023
        char    *escSchemaName = NULL, *escTableName = NULL, *escColumnName = NULL;
2007
2025
        ConnInfo   *ci;
2008
2026
        ConnectionClass *conn;
2009
2027
        SQLSMALLINT     internal_asis_type = SQL_C_CHAR, cbSchemaName;
2010
 
        SQLINTEGER      greloid;
2011
2028
        const char      *like_or_eq = likeop, *op_string;
2012
2029
        const char      *szSchemaName;
2013
2030
 
2070
2087
        op_string = gen_opestr(like_or_eq, conn);
2071
2088
        if (conn->schema_support)
2072
2089
        {
2073
 
                strncpy(columns_query,
 
2090
                snprintf(columns_query, sizeof(columns_query),
2074
2091
                        "select n.nspname, c.relname, a.attname, a.atttypid"
2075
2092
                        ", t.typname, a.attnum, a.attlen, a.atttypmod, a.attnotnull"
2076
 
                        ", c.relhasrules, c.relkind, c.oid, d.adsrc from (((pg_catalog.pg_class c"
 
2093
                        ", c.relhasrules, c.relkind, c.oid, %s, %s from (((pg_catalog.pg_class c"
2077
2094
                        " inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
2078
 
                        sizeof(columns_query));
 
2095
                        PG_VERSION_GE(conn, 7.4) ?
 
2096
                        "pg_get_expr(d.adbin, d.adrelid)" : "d.adsrc",
 
2097
                        PG_VERSION_GE(conn, 7.4) ?
 
2098
                        "case t.typtype when 'd' then t.typbasetype else 0 end, t.typtypmod"
 
2099
                                        : "0, -1");
2079
2100
                if (search_by_ids)
2080
2101
                        snprintf_add(columns_query, sizeof(columns_query), " and c.oid = %u", reloid);
2081
2102
                else
2106
2127
                snprintf(columns_query, sizeof(columns_query),
2107
2128
                        "select u.usename, c.relname, a.attname, a.atttypid"
2108
2129
                        ", t.typname, a.attnum, a.attlen, %s, a.attnotnull"
2109
 
                        ", c.relhasrules, c.relkind, c.oid, NULL from pg_user u"
2110
 
                        ", pg_class c, pg_attribute a, pg_type t where"
 
2130
                        ", c.relhasrules, c.relkind, c.oid, NULL, 0, -1 from"
 
2131
                        "  pg_user u, pg_class c, pg_attribute a, pg_type t where"
2111
2132
                        "  u.usesysid = c.relowner and c.oid= a.attrelid"
2112
2133
                        "  and a.atttypid = t.oid and (a.attnum > 0)",
2113
2134
                        PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
2143
2164
            (res = SC_get_Result(col_stmt)) &&
2144
2165
            0 == QR_get_num_total_tuples(res))
2145
2166
        {
2146
 
                const char *user = CC_get_username(conn);
2147
 
 
2148
 
                /*
2149
 
                 * If specified schema name == user_name and
2150
 
                 * the current schema is 'public',
2151
 
                 * retry the 'public' schema.
2152
 
                 */
2153
2167
                if (!search_by_ids &&
2154
 
                    szSchemaName &&
2155
 
                    (cbSchemaName == SQL_NTS ||
2156
 
                     cbSchemaName == (SQLSMALLINT) strlen(user)) &&
2157
 
                    strnicmp(szSchemaName, user, strlen(user)) == 0 &&
2158
 
                    stricmp(CC_get_current_schema(conn), pubstr) == 0)
 
2168
                    allow_public_schema(conn, szSchemaName, cbSchemaName))
2159
2169
                {
2160
2170
                        PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
2161
2171
                        hcol_stmt = NULL;
2189
2199
                goto cleanup;
2190
2200
        }
2191
2201
 
2192
 
        result = PGAPI_BindCol(hcol_stmt, 4, SQL_C_LONG,
 
2202
        result = PGAPI_BindCol(hcol_stmt, 4, SQL_C_ULONG,
2193
2203
                                                   &field_type, 4, NULL);
2194
2204
        if (!SQL_SUCCEEDED(result))
2195
2205
        {
2263
2273
                goto cleanup;
2264
2274
        }
2265
2275
 
 
2276
        result = PGAPI_BindCol(hcol_stmt, 14, SQL_C_ULONG,
 
2277
                                        &basetype, sizeof(basetype), NULL);
 
2278
        if (!SQL_SUCCEEDED(result))
 
2279
        {
 
2280
                SC_error_copy(stmt, col_stmt, TRUE);
 
2281
                goto cleanup;
 
2282
        }
 
2283
 
 
2284
        result = PGAPI_BindCol(hcol_stmt, 15, SQL_C_LONG,
 
2285
                                        &typmod, sizeof(typmod), NULL);
 
2286
        if (!SQL_SUCCEEDED(result))
 
2287
        {
 
2288
                SC_error_copy(stmt, col_stmt, TRUE);
 
2289
                goto cleanup;
 
2290
        }
 
2291
 
2266
2292
        if (res = QR_Constructor(), !res)
2267
2293
        {
2268
2294
                SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for PGAPI_Columns result.", func);
2279
2305
        result_cols = NUM_OF_COLUMNS_FIELDS;
2280
2306
        extend_column_bindings(SC_get_ARDF(stmt), result_cols);
2281
2307
 
2282
 
        stmt->catalog_result = TRUE;
 
2308
        /*
 
2309
         * Setting catalog_result here affects the behavior of
 
2310
         * pgtype_xxx() functions. So set it later.
 
2311
         * stmt->catalog_result = TRUE;
 
2312
         */
2283
2313
        /* set the field names */
2284
2314
        QR_set_num_fields(res, result_cols);
2285
2315
        QR_set_field_info_v(res, COLUMNS_CATALOG_NAME, "TABLE_QUALIFIER", PG_TYPE_VARCHAR, MAX_INFO_STRING);
2308
2338
        QR_set_field_info_v(res, COLUMNS_FIELD_TYPE, "FIELD_TYPE", PG_TYPE_INT4, 4);
2309
2339
        QR_set_field_info_v(res, COLUMNS_AUTO_INCREMENT, "AUTO_INCREMENT", PG_TYPE_INT4, 4);
2310
2340
        QR_set_field_info_v(res, COLUMNS_PHYSICAL_NUMBER, "PHYSICAL NUMBER", PG_TYPE_INT2, 2);
2311
 
        QR_set_field_info_v(res, COLUMNS_TABLE_OID, "TABLE OID", PG_TYPE_INT4, 4);
 
2341
        QR_set_field_info_v(res, COLUMNS_TABLE_OID, "TABLE OID", PG_TYPE_OID, 4);
 
2342
        QR_set_field_info_v(res, COLUMNS_BASE_TYPEID, "BASE TYPEID", PG_TYPE_OID, 4);
2312
2343
 
2313
2344
        ordinal = 1;
2314
2345
        result = PGAPI_Fetch(hcol_stmt);
2344
2375
                        set_tuplefield_int2(&tuple[COLUMNS_DATA_TYPE], sqltype);
2345
2376
                        set_tuplefield_string(&tuple[COLUMNS_TYPE_NAME], "OID");
2346
2377
 
2347
 
                        set_tuplefield_int4(&tuple[COLUMNS_PRECISION], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC));
2348
 
                        set_tuplefield_int4(&tuple[COLUMNS_LENGTH], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC));
 
2378
                        set_tuplefield_int4(&tuple[COLUMNS_PRECISION], pgtype_column_size(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
 
2379
                        set_tuplefield_int4(&tuple[COLUMNS_LENGTH], pgtype_buffer_length(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2349
2380
                        set_nullfield_int2(&tuple[COLUMNS_SCALE], pgtype_decimal_digits(stmt, the_type, PG_STATIC));
2350
 
                        set_nullfield_int2(&tuple[COLUMNS_RADIX], pgtype_radix(stmt, the_type));
 
2381
                        set_nullfield_int2(&tuple[COLUMNS_RADIX], pgtype_radix(conn, the_type));
2351
2382
                        set_tuplefield_int2(&tuple[COLUMNS_NULLABLE], SQL_NO_NULLS);
2352
2383
                        set_tuplefield_string(&tuple[COLUMNS_REMARKS], NULL_STRING);
2353
2384
 
2359
2390
                        set_tuplefield_int4(&tuple[COLUMNS_ORDINAL_POSITION], ordinal);
2360
2391
                        set_tuplefield_string(&tuple[COLUMNS_IS_NULLABLE], "No");
2361
2392
#endif /* ODBCVER */
2362
 
                        set_tuplefield_int4(&tuple[COLUMNS_DISPLAY_SIZE], pgtype_display_size(stmt, the_type, PG_STATIC, PG_STATIC));
 
2393
                        set_tuplefield_int4(&tuple[COLUMNS_DISPLAY_SIZE], pgtype_display_size(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2363
2394
                        set_tuplefield_int4(&tuple[COLUMNS_FIELD_TYPE], the_type);
2364
2395
                        set_tuplefield_int4(&tuple[COLUMNS_AUTO_INCREMENT], TRUE);
2365
2396
                        set_tuplefield_int2(&tuple[COLUMNS_PHYSICAL_NUMBER], OID_ATTNUM);
2366
2397
                        set_tuplefield_int4(&tuple[COLUMNS_TABLE_OID], greloid);
 
2398
                        set_tuplefield_int4(&tuple[COLUMNS_BASE_TYPEID], 0);
2367
2399
                        ordinal++;
2368
2400
                }
2369
2401
        }
2396
2428
                set_tuplefield_string(&tuple[COLUMNS_TABLE_NAME], table_name);
2397
2429
                set_tuplefield_string(&tuple[COLUMNS_COLUMN_NAME], field_name);
2398
2430
                auto_unique = SQL_FALSE;
 
2431
                if (field_type = pg_true_type(conn, field_type, basetype), field_type == basetype)
 
2432
                        mod_length = typmod;
2399
2433
                switch (field_type)
2400
2434
                {
2401
2435
                        case PG_TYPE_INT4:
2434
2468
                qlog("%s: table='%s',field_name='%s',type=%d,name='%s'\n",
2435
2469
                         func, table_name, field_name, field_type, field_type_name);
2436
2470
 
 
2471
#ifdef  USE_OLD_IMPL
2437
2472
                useStaticPrecision = TRUE;
2438
2473
                useStaticScale = TRUE;
2439
2474
 
2505
2540
#endif /* UNICODE_SUPPORT */
2506
2541
                        set_tuplefield_int4(&tuple[COLUMNS_LENGTH], field_length);
2507
2542
#if (ODBCVER >= 0x0300)
2508
 
                        set_tuplefield_int4(&tuple[COLUMNS_CHAR_OCTET_LENGTH], pgtype_transfer_octet_length(stmt, field_type, PG_STATIC, PG_STATIC));
 
2543
                        set_tuplefield_int4(&tuple[COLUMNS_CHAR_OCTET_LENGTH], pgtype_transfer_octet_length(conn, field_type, mod_length));
2509
2544
#endif /* ODBCVER */
2510
2545
                        set_tuplefield_int4(&tuple[COLUMNS_DISPLAY_SIZE], mod_length);
2511
2546
                }
2512
2547
 
2513
2548
                if (useStaticPrecision)
2514
2549
                {
2515
 
                        mylog("%s: field type is OTHER: field_type = %d, pgtype_length = %d\n", func, field_type, pgtype_buffer_length(stmt, field_type, PG_STATIC, PG_STATIC));
 
2550
                        mylog("%s: field type is OTHER: field_type = %d, pgtype_length = %d\n", func, field_type, pgtype_buffer_length(stmt, field_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2516
2551
 
2517
 
                        set_tuplefield_int4(&tuple[COLUMNS_PRECISION], pgtype_column_size(stmt, field_type, PG_STATIC, PG_STATIC));
2518
 
                        set_tuplefield_int4(&tuple[COLUMNS_LENGTH], pgtype_buffer_length(stmt, field_type, PG_STATIC, PG_STATIC));
 
2552
                        set_tuplefield_int4(&tuple[COLUMNS_PRECISION], pgtype_column_size(stmt, field_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
 
2553
                        set_tuplefield_int4(&tuple[COLUMNS_LENGTH], pgtype_buffer_length(stmt, field_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2519
2554
#if (ODBCVER >= 0x0300)
2520
2555
                        set_tuplefield_null(&tuple[COLUMNS_CHAR_OCTET_LENGTH]);
2521
2556
#endif /* ODBCVER */
2522
 
                        set_tuplefield_int4(&tuple[COLUMNS_DISPLAY_SIZE], pgtype_display_size(stmt, field_type, PG_STATIC, PG_STATIC));
 
2557
                        set_tuplefield_int4(&tuple[COLUMNS_DISPLAY_SIZE], pgtype_display_size(stmt, field_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2523
2558
                }
2524
2559
                if (useStaticScale)
2525
2560
                {
2528
2563
 
2529
2564
                if (SQL_TYPE_NULL == sqltype)
2530
2565
                {
2531
 
                        sqltype = pgtype_to_concise_type(stmt, field_type, PG_STATIC);
2532
 
                        concise_type = pgtype_to_sqldesctype(stmt, field_type, PG_STATIC);
 
2566
                        sqltype = pgtype_attr_to_concise_type(conn, field_type, mod_length, -1);
 
2567
                        concise_type = pgtype_attr_to_sqldesctype(conn, field_type, mod_length);
2533
2568
                }
2534
2569
                else
2535
2570
                        concise_type = sqltype;
 
2571
#else /* USE_OLD_IMPL */
 
2572
                /* Subtract the header length */
 
2573
                switch (field_type)
 
2574
                {
 
2575
                        case PG_TYPE_DATETIME:
 
2576
                        case PG_TYPE_TIMESTAMP_NO_TMZONE:
 
2577
                        case PG_TYPE_TIME:
 
2578
                        case PG_TYPE_TIME_WITH_TMZONE:
 
2579
                                break;
 
2580
                        default:
 
2581
                                mod_length -= 4;
 
2582
                }
 
2583
                set_tuplefield_int4(&tuple[COLUMNS_PRECISION], pgtype_attr_column_size(conn, field_type, mod_length, PG_UNSPECIFIED, UNKNOWNS_AS_DEFAULT));
 
2584
                set_tuplefield_int4(&tuple[COLUMNS_LENGTH], pgtype_attr_buffer_length(conn, field_type, mod_length, PG_UNSPECIFIED, UNKNOWNS_AS_DEFAULT));
 
2585
                set_tuplefield_int4(&tuple[COLUMNS_DISPLAY_SIZE], pgtype_attr_display_size(conn, field_type, mod_length, PG_UNSPECIFIED, UNKNOWNS_AS_DEFAULT));
 
2586
                set_nullfield_int2(&tuple[COLUMNS_SCALE], pgtype_attr_decimal_digits(conn, field_type, mod_length, PG_UNSPECIFIED, UNKNOWNS_AS_DEFAULT));
 
2587
 
 
2588
                sqltype = pgtype_attr_to_concise_type(conn, field_type, mod_length, PG_UNSPECIFIED);
 
2589
                concise_type = pgtype_attr_to_sqldesctype(conn, field_type, mod_length);
 
2590
#endif /* USE_OLD_IMPL */
 
2591
 
2536
2592
                set_tuplefield_int2(&tuple[COLUMNS_DATA_TYPE], sqltype);
2537
2593
 
2538
 
                set_nullfield_int2(&tuple[COLUMNS_RADIX], pgtype_radix(stmt, field_type));
2539
 
                set_tuplefield_int2(&tuple[COLUMNS_NULLABLE], (Int2) (not_null[0] == '1' ? SQL_NO_NULLS : pgtype_nullable(stmt, field_type)));
 
2594
                set_nullfield_int2(&tuple[COLUMNS_RADIX], pgtype_radix(conn, field_type));
 
2595
                set_tuplefield_int2(&tuple[COLUMNS_NULLABLE], (Int2) (not_null[0] == '1' ? SQL_NO_NULLS : pgtype_nullable(conn, field_type)));
2540
2596
                set_tuplefield_string(&tuple[COLUMNS_REMARKS], NULL_STRING);
2541
2597
#if (ODBCVER >= 0x0300)
2542
2598
                if (attdef && strlen(attdef) > INFO_VARCHAR_SIZE)
2544
2600
                else
2545
2601
                        set_tuplefield_string(&tuple[COLUMNS_COLUMN_DEF], attdef);
2546
2602
                set_tuplefield_int2(&tuple[COLUMNS_SQL_DATA_TYPE], concise_type);
2547
 
                set_nullfield_int2(&tuple[COLUMNS_SQL_DATETIME_SUB], pgtype_to_datetime_sub(stmt, field_type));
 
2603
                set_nullfield_int2(&tuple[COLUMNS_SQL_DATETIME_SUB], pgtype_attr_to_datetime_sub(conn, field_type, mod_length));
 
2604
                set_tuplefield_int4(&tuple[COLUMNS_CHAR_OCTET_LENGTH], pgtype_attr_transfer_octet_length(conn, field_type, mod_length, UNKNOWNS_AS_DEFAULT));
2548
2605
                set_tuplefield_int4(&tuple[COLUMNS_ORDINAL_POSITION], ordinal);
2549
2606
                set_tuplefield_null(&tuple[COLUMNS_IS_NULLABLE]);
2550
2607
#endif /* ODBCVER */
2552
2609
                set_tuplefield_int4(&tuple[COLUMNS_AUTO_INCREMENT], auto_unique);
2553
2610
                set_tuplefield_int2(&tuple[COLUMNS_PHYSICAL_NUMBER], field_number);
2554
2611
                set_tuplefield_int4(&tuple[COLUMNS_TABLE_OID], greloid);
 
2612
                set_tuplefield_int4(&tuple[COLUMNS_BASE_TYPEID], basetype);
2555
2613
                ordinal++;
2556
2614
 
2557
2615
                result = PGAPI_Fetch(hcol_stmt);
2584
2642
                set_tuplefield_string(&tuple[COLUMNS_COLUMN_NAME], "xmin");
2585
2643
                sqltype = pgtype_to_concise_type(stmt, the_type, PG_STATIC);
2586
2644
                set_tuplefield_int2(&tuple[COLUMNS_DATA_TYPE], sqltype);
2587
 
                set_tuplefield_string(&tuple[COLUMNS_TYPE_NAME], pgtype_to_name(stmt, the_type, FALSE));
2588
 
                set_tuplefield_int4(&tuple[COLUMNS_PRECISION], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC));
2589
 
                set_tuplefield_int4(&tuple[COLUMNS_LENGTH], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC));
 
2645
                set_tuplefield_string(&tuple[COLUMNS_TYPE_NAME], pgtype_to_name(stmt, the_type, PG_UNSPECIFIED, FALSE));
 
2646
                set_tuplefield_int4(&tuple[COLUMNS_PRECISION], pgtype_column_size(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
 
2647
                set_tuplefield_int4(&tuple[COLUMNS_LENGTH], pgtype_buffer_length(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2590
2648
                set_nullfield_int2(&tuple[COLUMNS_SCALE], pgtype_decimal_digits(stmt, the_type, PG_STATIC));
2591
 
                set_nullfield_int2(&tuple[COLUMNS_RADIX], pgtype_radix(stmt, the_type));
 
2649
                set_nullfield_int2(&tuple[COLUMNS_RADIX], pgtype_radix(conn, the_type));
2592
2650
                set_tuplefield_int2(&tuple[COLUMNS_NULLABLE], SQL_NO_NULLS);
2593
2651
                set_tuplefield_string(&tuple[COLUMNS_REMARKS], NULL_STRING);
2594
2652
#if (ODBCVER >= 0x0300)
2599
2657
                set_tuplefield_int4(&tuple[COLUMNS_ORDINAL_POSITION], ordinal);
2600
2658
                set_tuplefield_string(&tuple[COLUMNS_IS_NULLABLE], "No");
2601
2659
#endif /* ODBCVER */
2602
 
                set_tuplefield_int4(&tuple[COLUMNS_DISPLAY_SIZE], pgtype_display_size(stmt, the_type, PG_STATIC, PG_STATIC));
 
2660
                set_tuplefield_int4(&tuple[COLUMNS_DISPLAY_SIZE], pgtype_display_size(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2603
2661
                set_tuplefield_int4(&tuple[COLUMNS_FIELD_TYPE], the_type);
2604
2662
                set_tuplefield_int4(&tuple[COLUMNS_AUTO_INCREMENT], FALSE);
2605
2663
                set_tuplefield_int2(&tuple[COLUMNS_PHYSICAL_NUMBER], XMIN_ATTNUM);
2606
2664
                set_tuplefield_int4(&tuple[COLUMNS_TABLE_OID], greloid);
 
2665
                set_tuplefield_int4(&tuple[COLUMNS_BASE_TYPEID], 0);
2607
2666
                ordinal++;
2608
2667
        }
2609
2668
        result = SQL_SUCCESS;
2615
2674
         * results can be retrieved.
2616
2675
         */
2617
2676
        stmt->status = STMT_FINISHED;
 
2677
        stmt->catalog_result = TRUE;
2618
2678
 
2619
2679
        /* set up the current tuple pointer for SQLFetch */
2620
2680
        stmt->currTuple = -1;
2665
2725
        SQLSMALLINT     internal_asis_type = SQL_C_CHAR, cbSchemaName;
2666
2726
        const char      *szSchemaName, *eq_string;
2667
2727
 
2668
 
        mylog("%s: entering...stmt=%p scnm=%p len=%d colType=%d\n", func, stmt, szTableOwner, cbTableOwner, fColType);
 
2728
        mylog("%s: entering...stmt=%p scnm=%p len=%d colType=%d scope=%d\n", func, stmt, szTableOwner, cbTableOwner, fColType, fScope);
2669
2729
 
2670
2730
        if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result)
2671
2731
                return result;
2741
2801
            (res = SC_get_Result(col_stmt)) &&
2742
2802
            0 == QR_get_num_total_tuples(res))
2743
2803
        {
2744
 
                const char *user = CC_get_username(conn);
2745
 
 
2746
 
                /*
2747
 
                 * If specified schema name == user_name and
2748
 
                 * the current schema is 'public',
2749
 
                 * retry the 'public' schema.
2750
 
                 */
2751
 
                if (szSchemaName &&
2752
 
                    (cbSchemaName == SQL_NTS ||
2753
 
                     cbSchemaName == (SQLSMALLINT) strlen(user)) &&
2754
 
                    strnicmp(szSchemaName, user, strlen(user)) == 0 &&
2755
 
                    stricmp(CC_get_current_schema(conn), pubstr) == 0)
 
2804
                if (allow_public_schema(conn, szSchemaName, cbSchemaName))
2756
2805
                {
2757
2806
                        PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
2758
2807
                        hcol_stmt = NULL;
2831
2880
                        set_tuplefield_null(&tuple[0]);
2832
2881
                        set_tuplefield_string(&tuple[1], "ctid");
2833
2882
                        set_tuplefield_int2(&tuple[2], pgtype_to_concise_type(stmt, the_type, PG_STATIC));
2834
 
                        set_tuplefield_string(&tuple[3], pgtype_to_name(stmt, the_type, FALSE));
2835
 
                        set_tuplefield_int4(&tuple[4], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC));
2836
 
                        set_tuplefield_int4(&tuple[5], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC));
 
2883
                        set_tuplefield_string(&tuple[3], pgtype_to_name(stmt, the_type, PG_UNSPECIFIED, FALSE));
 
2884
                        set_tuplefield_int4(&tuple[4], pgtype_column_size(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
 
2885
                        set_tuplefield_int4(&tuple[5], pgtype_buffer_length(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2837
2886
                        set_tuplefield_int2(&tuple[6], pgtype_decimal_digits(stmt, the_type, PG_STATIC));
2838
2887
                        set_tuplefield_int2(&tuple[7], SQL_PC_NOT_PSEUDO);
2839
2888
inolog("Add ctid\n");
2855
2904
                        set_tuplefield_int2(&tuple[0], SQL_SCOPE_SESSION);
2856
2905
                        set_tuplefield_string(&tuple[1], OID_NAME);
2857
2906
                        set_tuplefield_int2(&tuple[2], pgtype_to_concise_type(stmt, the_type, PG_STATIC));
2858
 
                        set_tuplefield_string(&tuple[3], pgtype_to_name(stmt, the_type, TRUE));
2859
 
                        set_tuplefield_int4(&tuple[4], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC));
2860
 
                        set_tuplefield_int4(&tuple[5], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC));
 
2907
                        set_tuplefield_string(&tuple[3], pgtype_to_name(stmt, the_type, PG_UNSPECIFIED, TRUE));
 
2908
                        set_tuplefield_int4(&tuple[4], pgtype_column_size(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
 
2909
                        set_tuplefield_int4(&tuple[5], pgtype_buffer_length(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2861
2910
                        set_tuplefield_int2(&tuple[6], pgtype_decimal_digits(stmt, the_type, PG_STATIC));
2862
2911
                        set_tuplefield_int2(&tuple[7], SQL_PC_PSEUDO);
2863
2912
                }
2872
2921
                                set_tuplefield_null(&tuple[0]);
2873
2922
                                set_tuplefield_string(&tuple[1], "xmin");
2874
2923
                                set_tuplefield_int2(&tuple[2], pgtype_to_concise_type(stmt, the_type, PG_STATIC));
2875
 
                                set_tuplefield_string(&tuple[3], pgtype_to_name(stmt, the_type, FALSE));
2876
 
                                set_tuplefield_int4(&tuple[4], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC));
2877
 
                                set_tuplefield_int4(&tuple[5], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC));
 
2924
                                set_tuplefield_string(&tuple[3], pgtype_to_name(stmt, the_type, PG_UNSPECIFIED, FALSE));
 
2925
                                set_tuplefield_int4(&tuple[4], pgtype_column_size(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
 
2926
                                set_tuplefield_int4(&tuple[5], pgtype_buffer_length(stmt, the_type, PG_STATIC, UNKNOWNS_AS_DEFAULT));
2878
2927
                                set_tuplefield_int2(&tuple[6], pgtype_decimal_digits(stmt, the_type, PG_STATIC));
2879
2928
                                set_tuplefield_int2(&tuple[7], SQL_PC_PSEUDO);
2880
2929
                        }
2932
2981
                           *indx_stmt;
2933
2982
        char            column_name[MAX_INFO_STRING],
2934
2983
                        table_schemaname[MAX_INFO_STRING],
2935
 
                                relhasrules[10], relkind[8];
 
2984
                                relhasrules[10];
2936
2985
        struct columns_idx {
2937
2986
                int     pnum;
2938
2987
                char    *col_name;
3233
3282
                set_tuplefield_int2(&tuple[STATS_NON_UNIQUE], (Int2) (ci->drivers.unique_index ? FALSE : TRUE));
3234
3283
 
3235
3284
                /* no index qualifier */
3236
 
                set_tuplefield_string(&tuple[STATS_INDEX_QUALIFIER], CurrCat(conn));
 
3285
                set_tuplefield_string(&tuple[STATS_INDEX_QUALIFIER], GET_SCHEMA_NAME(table_schemaname));
3237
3286
 
3238
 
                snprintf(buf, sizeof(table_name), "%s_idx_fake_oid", table_name);
 
3287
                snprintf(buf, sizeof(buf), "%s_idx_fake_oid", table_name);
3239
3288
                set_tuplefield_string(&tuple[STATS_INDEX_NAME], buf);
3240
3289
 
3241
3290
                /*
3278
3327
                                        set_tuplefield_int2(&tuple[STATS_NON_UNIQUE], TRUE);
3279
3328
 
3280
3329
                                /* no index qualifier */
3281
 
                                set_tuplefield_string(&tuple[STATS_INDEX_QUALIFIER], CurrCat(conn));
 
3330
                                set_tuplefield_string(&tuple[STATS_INDEX_QUALIFIER], GET_SCHEMA_NAME(table_schemaname));
3282
3331
                                set_tuplefield_string(&tuple[STATS_INDEX_NAME], index_name);
3283
3332
 
3284
3333
                                /*
3415
3464
        size_t          cq_len,cq_size;
3416
3465
        char            *col_query;
3417
3466
        BOOL    search_pattern;
3418
 
        QResultClass    *res;
 
3467
        QResultClass    *res = NULL;
3419
3468
 
3420
3469
        mylog("%s: entering...\n", func);
3421
3470
 
3472
3521
        if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
3473
3522
        {
3474
3523
                SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
3475
 
                QR_Destructor(res);
3476
 
                return SQL_ERROR;
 
3524
                goto cleanup;
3477
3525
        }
3478
3526
        SC_set_Result(stmt, res);
3479
3527
 
3485
3533
        /* set up the current tuple pointer for SQLFetch */
3486
3534
        result = SQL_SUCCESS;
3487
3535
cleanup:
 
3536
        if (!SQL_SUCCEEDED(result))
 
3537
                QR_Destructor(res);
3488
3538
        /* set up the current tuple pointer for SQLFetch */
3489
3539
        stmt->status = STMT_FINISHED;
3490
3540
        stmt->currTuple = -1;
3675
3725
                                 */
3676
3726
                                if (conn->schema_support)
3677
3727
                                {
3678
 
                                        strncpy(tables_query,
 
3728
                                        strncpy_null(tables_query,
3679
3729
                                                "select ta.attname, ia.attnum, ic.relname, n.nspname, tc.relname"
3680
3730
                                                " from pg_catalog.pg_attribute ta,"
3681
3731
                                                " pg_catalog.pg_attribute ia, pg_catalog.pg_class tc,"
3692
3742
                                                , eq_string, escTableName, eq_string, pkscm);
3693
3743
                                        else
3694
3744
                                                snprintf(tbqry, tsize,
3695
 
                                                " where tc.oid = " FORMAT_UINTEGER
 
3745
                                                " where tc.oid = " FORMAT_UINT4
3696
3746
                                                , reloid);
3697
3747
 
3698
 
                                        strncat(tables_query,
 
3748
                                        strlcat(tables_query,
3699
3749
                                                " AND tc.oid = i.indrelid"
3700
3750
                                                " AND n.oid = tc.relnamespace"
3701
3751
                                                " AND i.indisprimary = 't'"
3710
3760
                                }
3711
3761
                                else
3712
3762
                                {
3713
 
                                        strncpy(tables_query, 
 
3763
                                        strncpy_null(tables_query, 
3714
3764
                                                "select ta.attname, ia.attnum, ic.relname, NULL, tc.relname"
3715
3765
                                                " from pg_attribute ta, pg_attribute ia, pg_class tc, pg_index i, pg_class ic"
3716
3766
                                                , sizeof(tables_query));
3723
3773
                                                , eq_string, escTableName);
3724
3774
                                        else
3725
3775
                                                snprintf(tbqry, tsize,
3726
 
                                                " where tc.oid = " FORMAT_UINTEGER, reloid);
 
3776
                                                " where tc.oid = " FORMAT_UINT4, reloid);
3727
3777
                                                
3728
 
                                        strncat(tables_query,
 
3778
                                        strlcat(tables_query,
3729
3779
                                                " AND tc.oid = i.indrelid"
3730
3780
                                                " AND i.indisprimary = 't'"
3731
3781
                                                " AND ia.attrelid = i.indexrelid"
3786
3836
        if (conn->schema_support &&
3787
3837
            SQL_NO_DATA_FOUND == result)
3788
3838
        {
3789
 
                const char *user = CC_get_username(conn);
3790
 
 
3791
 
                /*
3792
 
                 * If specified schema name == user_name and
3793
 
                 * the current schema is 'public',
3794
 
                 * retry the 'public' schema.
3795
 
                 */
3796
 
                if (0 == reloid && szSchemaName &&
3797
 
                    (cbSchemaName == SQL_NTS ||
3798
 
                     cbSchemaName == (SQLSMALLINT) strlen(user)) &&
3799
 
                    strnicmp(szSchemaName, user, strlen(user)) == 0 &&
3800
 
                    stricmp(CC_get_current_schema(conn), pubstr) == 0)
 
3839
                if (0 == reloid &&
 
3840
                    allow_public_schema(conn, szSchemaName, cbSchemaName))
3801
3841
                {
3802
3842
                        szSchemaName = pubstr;
3803
3843
                        cbSchemaName = SQL_NTS;
3953
3993
        return ret;
3954
3994
}
3955
3995
 
3956
 
RETCODE         SQL_API
3957
 
PGAPI_ForeignKeys(
 
3996
static RETCODE          SQL_API
 
3997
PGAPI_ForeignKeys_new(
 
3998
                HSTMT hstmt,
 
3999
                const SQLCHAR FAR * szPkTableQualifier, /* OA X*/
 
4000
                SQLSMALLINT cbPkTableQualifier,
 
4001
                const SQLCHAR FAR * szPkTableOwner, /* OA E*/
 
4002
                SQLSMALLINT cbPkTableOwner,
 
4003
                const SQLCHAR FAR * szPkTableName, /* OA(R) E*/
 
4004
                SQLSMALLINT cbPkTableName,
 
4005
                const SQLCHAR FAR * szFkTableQualifier, /* OA X*/
 
4006
                SQLSMALLINT cbFkTableQualifier,
 
4007
                const SQLCHAR FAR * szFkTableOwner, /* OA E*/
 
4008
                SQLSMALLINT cbFkTableOwner,
 
4009
                const SQLCHAR FAR * szFkTableName, /* OA(R) E*/
 
4010
                SQLSMALLINT cbFkTableName);
 
4011
 
 
4012
static RETCODE          SQL_API
 
4013
PGAPI_ForeignKeys_old(
3958
4014
                        HSTMT hstmt,
3959
4015
                        const SQLCHAR FAR * szPkTableQualifier, /* OA X*/
3960
4016
                        SQLSMALLINT cbPkTableQualifier,
4427
4483
                                set_tuplefield_string(&tuple[FKS_PKCOLUMN_NAME], pkey_text);
4428
4484
 
4429
4485
                                mylog("%s: fk_table_needed = '%s', fkey_ptr = '%s'\n", func, fk_table_needed, fkey_text);
4430
 
                                set_tuplefield_null(&tuple[FKS_FKTABLE_CAT]);
 
4486
                                set_tuplefield_string(&tuple[FKS_FKTABLE_CAT], CurrCat(conn));
4431
4487
                                set_tuplefield_string(&tuple[FKS_FKTABLE_SCHEM], GET_SCHEMA_NAME(schema_needed));
4432
4488
                                set_tuplefield_string(&tuple[FKS_FKTABLE_NAME], fk_table_needed);
4433
4489
                                set_tuplefield_string(&tuple[FKS_FKCOLUMN_NAME], fkey_text);
4754
4810
                                set_tuplefield_string(&tuple[FKS_PKCOLUMN_NAME], pkey_text);
4755
4811
 
4756
4812
                                mylog("fk_table = '%s', fkey_ptr = '%s'\n", fk_table_fetched, fkey_text);
4757
 
                                set_tuplefield_null(&tuple[FKS_FKTABLE_CAT]);
 
4813
                                set_tuplefield_string(&tuple[FKS_FKTABLE_CAT], CurrCat(conn));
4758
4814
                                set_tuplefield_string(&tuple[FKS_FKTABLE_SCHEM], GET_SCHEMA_NAME(schema_fetched));
4759
4815
                                set_tuplefield_string(&tuple[FKS_FKTABLE_NAME], fk_table_fetched);
4760
4816
                                set_tuplefield_string(&tuple[FKS_FKCOLUMN_NAME], fkey_text);
4836
4892
        return ret;
4837
4893
}
4838
4894
 
 
4895
RETCODE         SQL_API
 
4896
PGAPI_ForeignKeys(
 
4897
                        HSTMT hstmt,
 
4898
                        const SQLCHAR FAR * szPkTableQualifier, /* OA X*/
 
4899
                        SQLSMALLINT cbPkTableQualifier,
 
4900
                        const SQLCHAR FAR * szPkTableOwner, /* OA E*/
 
4901
                        SQLSMALLINT cbPkTableOwner,
 
4902
                        const SQLCHAR FAR * szPkTableName, /* OA(R) E*/
 
4903
                        SQLSMALLINT cbPkTableName,
 
4904
                        const SQLCHAR FAR * szFkTableQualifier, /* OA X*/
 
4905
                        SQLSMALLINT cbFkTableQualifier,
 
4906
                        const SQLCHAR FAR * szFkTableOwner, /* OA E*/
 
4907
                        SQLSMALLINT cbFkTableOwner,
 
4908
                        const SQLCHAR FAR * szFkTableName, /* OA(R) E*/
 
4909
                        SQLSMALLINT cbFkTableName)
 
4910
{
 
4911
        ConnectionClass *conn = SC_get_conn(((StatementClass *) hstmt));
 
4912
        if (PG_VERSION_GE(conn, 8.1))
 
4913
                return PGAPI_ForeignKeys_new(hstmt,
 
4914
                                szPkTableQualifier, cbPkTableQualifier,
 
4915
                                szPkTableOwner, cbPkTableOwner,
 
4916
                                szPkTableName, cbPkTableName,
 
4917
                                szFkTableQualifier, cbFkTableQualifier,
 
4918
                                szFkTableOwner, cbFkTableOwner,
 
4919
                                szFkTableName, cbFkTableName);
 
4920
        else
 
4921
                return PGAPI_ForeignKeys_old(hstmt,
 
4922
                                szPkTableQualifier, cbPkTableQualifier,
 
4923
                                szPkTableOwner, cbPkTableOwner,
 
4924
                                szPkTableName, cbPkTableName,
 
4925
                                szFkTableQualifier, cbFkTableQualifier,
 
4926
                                szFkTableOwner, cbFkTableOwner,
 
4927
                                szFkTableName, cbFkTableName);
 
4928
}
 
4929
 
4839
4930
 
4840
4931
#define PRORET_COUNT
4841
4932
#define DISPLAY_ARGNAME
4865
4956
        QResultClass *res, *tres;
4866
4957
        SQLLEN          tcount;
4867
4958
        OID             pgtype;
4868
 
        Int4            paramcount, i, j;
 
4959
        Int4            paramcount, column_size, i, j;
4869
4960
        RETCODE         result;
4870
4961
        BOOL            search_pattern, bRetset;
4871
4962
        const char      *like_or_eq, *op_string, *retset;
5045
5136
                                set_tuplefield_string(&tuple[PROCOLS_COLUMN_NAME], NULL_STRING);
5046
5137
                                set_tuplefield_int2(&tuple[PROCOLS_COLUMN_TYPE], SQL_RETURN_VALUE);
5047
5138
                                set_tuplefield_int2(&tuple[PROCOLS_DATA_TYPE], pgtype_to_concise_type(stmt, pgtype, PG_STATIC));
5048
 
                                set_tuplefield_string(&tuple[PROCOLS_TYPE_NAME], pgtype_to_name(stmt, pgtype, FALSE));
5049
 
                                set_nullfield_int4(&tuple[PROCOLS_COLUMN_SIZE], pgtype_column_size(stmt, pgtype, PG_STATIC, PG_STATIC));
5050
 
                                set_tuplefield_int4(&tuple[PROCOLS_BUFFER_LENGTH], pgtype_buffer_length(stmt, pgtype, PG_STATIC, PG_STATIC));
 
5139
                                set_tuplefield_string(&tuple[PROCOLS_TYPE_NAME], pgtype_to_name(stmt, pgtype, PG_UNSPECIFIED, FALSE));
 
5140
                                column_size = pgtype_column_size(stmt, pgtype, PG_STATIC, UNKNOWNS_AS_DEFAULT);
 
5141
                                set_nullfield_int4(&tuple[PROCOLS_COLUMN_SIZE], column_size);
 
5142
                                set_tuplefield_int4(&tuple[PROCOLS_BUFFER_LENGTH], pgtype_buffer_length(stmt, pgtype, PG_STATIC, UNKNOWNS_AS_DEFAULT));
5051
5143
                                set_nullfield_int2(&tuple[PROCOLS_DECIMAL_DIGITS], pgtype_decimal_digits(stmt, pgtype, PG_STATIC));
5052
 
                                set_nullfield_int2(&tuple[PROCOLS_NUM_PREC_RADIX], pgtype_radix(stmt, pgtype));
 
5144
                                set_nullfield_int2(&tuple[PROCOLS_NUM_PREC_RADIX], pgtype_radix(conn, pgtype));
5053
5145
                                set_tuplefield_int2(&tuple[PROCOLS_NULLABLE], SQL_NULLABLE_UNKNOWN);
5054
5146
                                set_tuplefield_null(&tuple[PROCOLS_REMARKS]);
5055
5147
#if (ODBCVER >= 0x0300)
5056
5148
                                set_tuplefield_null(&tuple[PROCOLS_COLUMN_DEF]);
5057
5149
                                set_nullfield_int2(&tuple[PROCOLS_SQL_DATA_TYPE], pgtype_to_sqldesctype(stmt, pgtype, PG_STATIC));
5058
 
                                set_nullfield_int2(&tuple[PROCOLS_SQL_DATETIME_SUB], pgtype_to_datetime_sub(stmt, pgtype));
5059
 
                                set_nullfield_int4(&tuple[PROCOLS_CHAR_OCTET_LENGTH], pgtype_transfer_octet_length(stmt, pgtype, PG_STATIC, PG_STATIC));
 
5150
                                set_nullfield_int2(&tuple[PROCOLS_SQL_DATETIME_SUB], pgtype_to_datetime_sub(stmt, pgtype, PG_UNSPECIFIED));
 
5151
                                set_nullfield_int4(&tuple[PROCOLS_CHAR_OCTET_LENGTH], pgtype_attr_transfer_octet_length(conn, pgtype, PG_UNSPECIFIED, UNKNOWNS_AS_DEFAULT));
5060
5152
                                set_tuplefield_int4(&tuple[PROCOLS_ORDINAL_POSITION], 0);
5061
5153
                                set_tuplefield_string(&tuple[PROCOLS_IS_NULLABLE], NULL_STRING);
5062
5154
#endif   /* ODBCVER >= 0x0300 */
5170
5262
                                else
5171
5263
                                        set_tuplefield_int2(&tuple[PROCOLS_COLUMN_TYPE], SQL_PARAM_INPUT);
5172
5264
                                set_tuplefield_int2(&tuple[PROCOLS_DATA_TYPE], pgtype_to_concise_type(stmt, pgtype, PG_STATIC));
5173
 
                                set_tuplefield_string(&tuple[PROCOLS_TYPE_NAME], pgtype_to_name(stmt, pgtype, FALSE));
5174
 
                                set_nullfield_int4(&tuple[PROCOLS_COLUMN_SIZE], pgtype_column_size(stmt, pgtype, PG_STATIC, PG_STATIC));
5175
 
                                set_tuplefield_int4(&tuple[PROCOLS_BUFFER_LENGTH], pgtype_buffer_length(stmt, pgtype, PG_STATIC, PG_STATIC));
 
5265
                                set_tuplefield_string(&tuple[PROCOLS_TYPE_NAME], pgtype_to_name(stmt, pgtype, PG_UNSPECIFIED, FALSE));
 
5266
                                column_size = pgtype_column_size(stmt, pgtype, PG_STATIC, UNKNOWNS_AS_DEFAULT);
 
5267
                                set_nullfield_int4(&tuple[PROCOLS_COLUMN_SIZE], column_size);
 
5268
                                set_tuplefield_int4(&tuple[PROCOLS_BUFFER_LENGTH], pgtype_buffer_length(stmt, pgtype, PG_STATIC, UNKNOWNS_AS_DEFAULT));
5176
5269
                                set_nullfield_int2(&tuple[PROCOLS_DECIMAL_DIGITS], pgtype_decimal_digits(stmt, pgtype, PG_STATIC));
5177
 
                                set_nullfield_int2(&tuple[PROCOLS_NUM_PREC_RADIX], pgtype_radix(stmt, pgtype));
 
5270
                                set_nullfield_int2(&tuple[PROCOLS_NUM_PREC_RADIX], pgtype_radix(conn, pgtype));
5178
5271
                                set_tuplefield_int2(&tuple[PROCOLS_NULLABLE], SQL_NULLABLE_UNKNOWN);
5179
5272
                                set_tuplefield_null(&tuple[PROCOLS_REMARKS]);
5180
5273
#if (ODBCVER >= 0x0300)
5181
5274
                                set_tuplefield_null(&tuple[PROCOLS_COLUMN_DEF]);
5182
5275
                                set_nullfield_int2(&tuple[PROCOLS_SQL_DATA_TYPE], pgtype_to_sqldesctype(stmt, pgtype, PG_STATIC));
5183
 
                                set_nullfield_int2(&tuple[PROCOLS_SQL_DATETIME_SUB], pgtype_to_datetime_sub(stmt, pgtype));
5184
 
                                set_nullfield_int4(&tuple[PROCOLS_CHAR_OCTET_LENGTH], pgtype_transfer_octet_length(stmt, pgtype, PG_STATIC, PG_STATIC));
 
5276
                                set_nullfield_int2(&tuple[PROCOLS_SQL_DATETIME_SUB], pgtype_to_datetime_sub(stmt, pgtype, PG_UNSPECIFIED));
 
5277
                                set_nullfield_int4(&tuple[PROCOLS_CHAR_OCTET_LENGTH], pgtype_attr_transfer_octet_length(conn, pgtype, PG_UNSPECIFIED, UNKNOWNS_AS_DEFAULT));
5185
5278
                                set_tuplefield_int4(&tuple[PROCOLS_ORDINAL_POSITION], j + 1);
5186
5279
                                set_tuplefield_string(&tuple[PROCOLS_IS_NULLABLE], NULL_STRING);
5187
5280
#endif   /* ODBCVER >= 0x0300 */
5209
5302
                        set_tuplefield_string(&tuple[PROCOLS_COLUMN_NAME], attname);
5210
5303
                        set_tuplefield_int2(&tuple[PROCOLS_COLUMN_TYPE], SQL_RESULT_COL);
5211
5304
                        set_tuplefield_int2(&tuple[PROCOLS_DATA_TYPE], pgtype_to_concise_type(stmt, typid, PG_STATIC));
5212
 
                        set_tuplefield_string(&tuple[PROCOLS_TYPE_NAME], pgtype_to_name(stmt, typid, FALSE));
5213
 
                        set_nullfield_int4(&tuple[PROCOLS_COLUMN_SIZE], pgtype_column_size(stmt, typid, PG_STATIC, PG_STATIC));
5214
 
                        set_tuplefield_int4(&tuple[PROCOLS_BUFFER_LENGTH], pgtype_buffer_length(stmt, typid, PG_STATIC, PG_STATIC));
 
5305
                        set_tuplefield_string(&tuple[PROCOLS_TYPE_NAME], pgtype_to_name(stmt, typid, PG_UNSPECIFIED, FALSE));
 
5306
                        column_size = pgtype_column_size(stmt, typid, PG_STATIC, UNKNOWNS_AS_DEFAULT);
 
5307
                        set_nullfield_int4(&tuple[PROCOLS_COLUMN_SIZE], column_size);
 
5308
                        set_tuplefield_int4(&tuple[PROCOLS_BUFFER_LENGTH], pgtype_buffer_length(stmt, typid, PG_STATIC, UNKNOWNS_AS_DEFAULT));
5215
5309
                        set_nullfield_int2(&tuple[PROCOLS_DECIMAL_DIGITS], pgtype_decimal_digits(stmt, typid, PG_STATIC));
5216
 
                        set_nullfield_int2(&tuple[PROCOLS_NUM_PREC_RADIX], pgtype_radix(stmt, typid));
 
5310
                        set_nullfield_int2(&tuple[PROCOLS_NUM_PREC_RADIX], pgtype_radix(conn, typid));
5217
5311
                        set_tuplefield_int2(&tuple[PROCOLS_NULLABLE], SQL_NULLABLE_UNKNOWN);
5218
5312
                        set_tuplefield_null(&tuple[PROCOLS_REMARKS]);
5219
5313
#if (ODBCVER >= 0x0300)
5220
5314
                        set_tuplefield_null(&tuple[PROCOLS_COLUMN_DEF]);
5221
5315
                        set_nullfield_int2(&tuple[PROCOLS_SQL_DATA_TYPE], pgtype_to_sqldesctype(stmt, typid, PG_STATIC));
5222
 
                        set_nullfield_int2(&tuple[PROCOLS_SQL_DATETIME_SUB], pgtype_to_datetime_sub(stmt, typid));
5223
 
                        set_nullfield_int4(&tuple[PROCOLS_CHAR_OCTET_LENGTH], pgtype_transfer_octet_length(stmt, typid, PG_STATIC, PG_STATIC));
 
5316
                        set_nullfield_int2(&tuple[PROCOLS_SQL_DATETIME_SUB], pgtype_to_datetime_sub(stmt, typid, PG_UNSPECIFIED));
 
5317
                        set_nullfield_int4(&tuple[PROCOLS_CHAR_OCTET_LENGTH], pgtype_attr_transfer_octet_length(conn, typid, PG_UNSPECIFIED, UNKNOWNS_AS_DEFAULT));
5224
5318
                        set_tuplefield_int4(&tuple[PROCOLS_ORDINAL_POSITION], 0);
5225
5319
                        set_tuplefield_string(&tuple[PROCOLS_IS_NULLABLE], NULL_STRING);
5226
5320
#endif   /* ODBCVER >= 0x0300 */
5509
5603
            (flag & PODBC_SEARCH_PUBLIC_SCHEMA) != 0 &&
5510
5604
            0 == tablecount)
5511
5605
        {
5512
 
                const char *user = CC_get_username(conn);
5513
 
 
5514
 
                /*
5515
 
                 * If specified schema name == user_name and
5516
 
                 * the current schema is 'public',
5517
 
                 * retry the 'public' schema.
5518
 
                 */
5519
 
                if (szSchemaName &&
5520
 
                    (cbSchemaName == SQL_NTS ||
5521
 
                     cbSchemaName == (SQLSMALLINT) strlen(user)) &&
5522
 
                    strnicmp(szSchemaName, user, strlen(user)) == 0 &&
5523
 
                    stricmp(CC_get_current_schema(conn), pubstr) == 0)
 
5606
                if (allow_public_schema(conn, szSchemaName, cbSchemaName))
5524
5607
                {
5525
5608
                        QR_Destructor(wres);
5526
5609
                        wres = NULL;
5689
5772
                ret = DiscardStatementSvp(stmt, ret, FALSE);
5690
5773
        return ret;
5691
5774
}
 
5775
 
 
5776
 
 
5777
static RETCODE          SQL_API
 
5778
PGAPI_ForeignKeys_new(
 
5779
                HSTMT hstmt,
 
5780
                const SQLCHAR FAR * szPkTableQualifier, /* OA X*/
 
5781
                SQLSMALLINT cbPkTableQualifier,
 
5782
                const SQLCHAR FAR * szPkTableOwner, /* OA E*/
 
5783
                SQLSMALLINT cbPkTableOwner,
 
5784
                const SQLCHAR FAR * szPkTableName, /* OA(R) E*/
 
5785
                SQLSMALLINT cbPkTableName,
 
5786
                const SQLCHAR FAR * szFkTableQualifier, /* OA X*/
 
5787
                SQLSMALLINT cbFkTableQualifier,
 
5788
                const SQLCHAR FAR * szFkTableOwner, /* OA E*/
 
5789
                SQLSMALLINT cbFkTableOwner,
 
5790
                const SQLCHAR FAR * szFkTableName, /* OA(R) E*/
 
5791
                SQLSMALLINT cbFkTableName)
 
5792
{
 
5793
        CSTR func = "PGAPI_ForeignKeys";
 
5794
        StatementClass  *stmt = (StatementClass *) hstmt;
 
5795
        QResultClass    *res = NULL;
 
5796
        RETCODE         ret = SQL_ERROR, result;
 
5797
        char            tables_query[INFO_INQUIRY_LEN];
 
5798
        char            *pk_table_needed = NULL, *escTableName = NULL;
 
5799
        char            *fk_table_needed = NULL;
 
5800
        char            schema_needed[SCHEMA_NAME_STORAGE_LEN + 1];
 
5801
        char            catName[SCHEMA_NAME_STORAGE_LEN],
 
5802
                        scmName1[SCHEMA_NAME_STORAGE_LEN],
 
5803
                        scmName2[SCHEMA_NAME_STORAGE_LEN];
 
5804
        const char      *relqual;
 
5805
        ConnectionClass *conn = SC_get_conn(stmt);
 
5806
 
 
5807
        const char *eq_string;
 
5808
 
 
5809
        mylog("%s: entering...stmt=%p\n", func, stmt);
 
5810
 
 
5811
        if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result)
 
5812
                return result;
 
5813
 
 
5814
        schema_needed[0] = '\0';
 
5815
#define return  DONT_CALL_RETURN_FROM_HERE???
 
5816
 
 
5817
        pk_table_needed = make_string(szPkTableName, cbPkTableName, NULL, 0);
 
5818
        fk_table_needed = make_string(szFkTableName, cbFkTableName, NULL, 0);
 
5819
 
 
5820
        eq_string = gen_opestr(eqop, conn);
 
5821
 
 
5822
        /*
 
5823
         * Case #2 -- Get the foreign keys in the specified table (fktab) that
 
5824
         * refer to the primary keys of other table(s).
 
5825
         */
 
5826
        if (NULL != fk_table_needed)
 
5827
        {
 
5828
                mylog("%s: entering Foreign Key Case #2", func);
 
5829
                escTableName = simpleCatalogEscape(fk_table_needed, SQL_NTS, NULL, conn);
 
5830
                schema_strcat(schema_needed, "%.*s", szFkTableOwner, cbFkTableOwner, szFkTableName, cbFkTableName, conn);
 
5831
                relqual = "\n   and  conrelid = c.oid";
 
5832
        }
 
5833
        /*
 
5834
         * Case #1 -- Get the foreign keys in other tables that refer to the
 
5835
         * primary key in the specified table (pktab).  i.e., Who points to
 
5836
         * me?
 
5837
         */
 
5838
        else if (NULL != pk_table_needed)
 
5839
        {
 
5840
                escTableName = simpleCatalogEscape(pk_table_needed, SQL_NTS, NULL, conn);
 
5841
                schema_strcat(schema_needed, "%.*s", szPkTableOwner, cbPkTableOwner, szPkTableName, cbPkTableName, conn);
 
5842
                relqual = "\n   and  confrelid = c.oid";
 
5843
        }
 
5844
        else
 
5845
        {
 
5846
                SC_set_error(stmt, STMT_INTERNAL_ERROR, "No tables specified to PGAPI_ForeignKeys.", func);
 
5847
                goto cleanup;
 
5848
        }
 
5849
 
 
5850
        if (conn->schema_support)
 
5851
        {
 
5852
                char    *escSchemaName;
 
5853
 
 
5854
                if (NULL != CurrCat(conn))
 
5855
                        snprintf(catName, sizeof(catName), "'%s'::name", CurrCat(conn));
 
5856
                else
 
5857
                        strcpy(catName, "NULL::name");
 
5858
                strcpy(scmName1, "n2.nspname");
 
5859
                strcpy(scmName2, "n1.nspname");
 
5860
                escSchemaName = simpleCatalogEscape(schema_needed, SQL_NTS, NULL, conn);
 
5861
 
 
5862
                snprintf(tables_query, sizeof(tables_query),
 
5863
                "select"
 
5864
                "       %s as PKTABLE_CAT"
 
5865
                ",\n    %s as PKTABLE_SCHEM"
 
5866
                ",\n    c2.relname as PKTABLE_NAME"
 
5867
                ",\n    a2.attname as PKCOLUMN_NAME"
 
5868
                ",\n    %s as FKTABLE_CAT"
 
5869
                ",\n    %s as FKTABLE_SCHEM"
 
5870
                ",\n    c1.relname as FKTABLE_NAME"
 
5871
                ",\n    a1.attname as FKCOLUMN_NAME"
 
5872
                ",\n    i::int2 as KEY_SEQ"
 
5873
                ",\n    case ref.confupdtype"
 
5874
                "\n             when 'c' then %d::int2"
 
5875
                "\n             when 'n' then %d::int2"
 
5876
                "\n             when 'd' then %d::int2"
 
5877
                "\n             when 'r' then %d::int2"
 
5878
                "\n             else %d::int2"
 
5879
                "\n     end as UPDATE_RULE"
 
5880
                ",\n    case ref.confdeltype"
 
5881
                "\n             when 'c' then %d::int2"
 
5882
                "\n             when 'n' then %d::int2"
 
5883
                "\n             when 'd' then %d::int2"
 
5884
                "\n             when 'r' then %d::int2"
 
5885
                "\n             else %d::int2"
 
5886
                "\n     end as DELETE_RULE"
 
5887
                ",\n    ref.conname as FK_NAME"
 
5888
                ",\n    cn.conname as PK_NAME"
 
5889
#if (ODBCVER >= 0x0300)
 
5890
                ",\n    case"
 
5891
                "\n             when ref.condeferrable then"
 
5892
                "\n                     case"
 
5893
                "\n                     when ref.condeferred then %d::int2"
 
5894
                "\n                     else %d::int2"
 
5895
                "\n                     end"
 
5896
                "\n             else %d::int2"
 
5897
                "\n     end as DEFERRABLITY"
 
5898
#endif /* ODBCVER */
 
5899
                "\n from"
 
5900
                "\n ((((((("
 
5901
                " (select cn.oid, conrelid, conkey, confrelid, confkey"
 
5902
                ",\n     generate_series(array_lower(conkey, 1), array_upper(conkey, 1)) as i"
 
5903
                ",\n     confupdtype, confdeltype, conname"
 
5904
                ",\n     condeferrable, condeferred"
 
5905
                "\n  from pg_catalog.pg_constraint cn"
 
5906
                ",\n    pg_catalog.pg_class c"
 
5907
                ",\n    pg_catalog.pg_namespace n"
 
5908
                "\n  where contype = 'f' %s"
 
5909
                "\n   and  relname %s'%s'"
 
5910
                "\n   and  n.oid = c.relnamespace"
 
5911
                "\n   and  n.nspname %s'%s'"
 
5912
                "\n ) ref"
 
5913
                "\n inner join pg_catalog.pg_class c1"
 
5914
                "\n  on c1.oid = ref.conrelid)"
 
5915
                "\n inner join pg_catalog.pg_namespace n1"
 
5916
                "\n  on  n1.oid = c1.relnamespace)"
 
5917
                "\n inner join pg_catalog.pg_attribute a1"
 
5918
                "\n  on  a1.attrelid = c1.oid"
 
5919
                "\n  and  a1.attnum = conkey[i])"
 
5920
                "\n inner join pg_catalog.pg_class c2"
 
5921
                "\n  on  c2.oid = ref.confrelid)"
 
5922
                "\n inner join pg_catalog.pg_namespace n2"
 
5923
                "\n  on  n2.oid = c2.relnamespace)"
 
5924
                "\n inner join pg_catalog.pg_attribute a2"
 
5925
                "\n  on  a2.attrelid = c2.oid"
 
5926
                "\n  and  a2.attnum = confkey[i])"
 
5927
                "\n left outer join pg_catalog.pg_constraint cn"
 
5928
                "\n  on cn.conrelid = ref.confrelid"
 
5929
                "\n  and cn.contype = 'p')"
 
5930
                , catName
 
5931
                , scmName1
 
5932
                , catName
 
5933
                , scmName2
 
5934
                , SQL_CASCADE
 
5935
                , SQL_SET_NULL
 
5936
                , SQL_SET_DEFAULT
 
5937
                , SQL_RESTRICT
 
5938
                , SQL_NO_ACTION
 
5939
                , SQL_CASCADE
 
5940
                , SQL_SET_NULL
 
5941
                , SQL_SET_DEFAULT
 
5942
                , SQL_RESTRICT
 
5943
                , SQL_NO_ACTION
 
5944
#if (ODBCVER >= 0x0300)
 
5945
                , SQL_INITIALLY_DEFERRED
 
5946
                , SQL_INITIALLY_IMMEDIATE
 
5947
                , SQL_NOT_DEFERRABLE
 
5948
#endif /* ODBCVER */
 
5949
                , relqual
 
5950
                , eq_string, escTableName
 
5951
                , eq_string, escSchemaName);
 
5952
 
 
5953
                free(escSchemaName);
 
5954
                if (NULL != pk_table_needed &&
 
5955
                    NULL != fk_table_needed)
 
5956
                {
 
5957
                        free(escTableName);
 
5958
                        escTableName = simpleCatalogEscape(pk_table_needed, SQL_NTS, NULL, conn);
 
5959
                        snprintf_add(tables_query, sizeof(tables_query),
 
5960
                                        "\n where c2.relname %s'%s'",
 
5961
                                        eq_string, escTableName);
 
5962
                }
 
5963
                strcat(tables_query, "\n  order by ref.oid, ref.i");
 
5964
        }
 
5965
        else
 
5966
        {
 
5967
                strcpy(catName, "NULL::name");
 
5968
                strcpy(scmName1, "NULL::name");
 
5969
                strcpy(scmName2, "NULL::name");
 
5970
 
 
5971
                snprintf(tables_query, sizeof(tables_query),
 
5972
                "select %s as PKTABLE_CAT"
 
5973
                ",\n    %s as PKTABLE_SCHEM"
 
5974
                ",\n    c2.relname as PKTABLE_NAME"
 
5975
                ",\n    a2.attname as PKCOLUMN_NAME"
 
5976
                ",\n    %s as FKTABLE_CAT"
 
5977
                ",\n    %s as FKTABLE_SCHEM"
 
5978
                ",\n    c1.relname as FKTABLE_NAME"
 
5979
                ",\n    a1.attname as FKCOLUMN_NAME"
 
5980
                ",\n    i::int2 as KEY_SEQ"
 
5981
                ",\n    case confupdtype"
 
5982
                "\n             when 'c' then %d::int2"
 
5983
                "\n             when 'n' then %d::int2"
 
5984
                "\n             when 'd' then %d::int2"
 
5985
                "\n             when 'r' then %d::int2"
 
5986
                "\n             else %d::int2"
 
5987
                "\n     end as UPDATE_RULE"
 
5988
                ",\n    case confdeltype"
 
5989
                "\n             when 'c' then %d::int2"
 
5990
                "\n             when 'n' then %d::int2"
 
5991
                "\n             when 'd' then %d::int2"
 
5992
                "\n             when 'r' then %d::int2"
 
5993
                "\n             else %d::int2"
 
5994
                "\n     end as DELETE_RULE"
 
5995
                ",\n    conname as FK_NAME"
 
5996
                ",\n    NULL::name as PK_NAME"
 
5997
#if (ODBCVER >= 0x0300)
 
5998
                ",\n    case"
 
5999
                "\n             when condeferrable then"
 
6000
                "\n                     case"
 
6001
                "\n                     when condeferred then %d::int2"
 
6002
                "\n                     else %d::int2"
 
6003
                "\n                     end"
 
6004
                "\n             else %d::int2"
 
6005
                "\n     end as DEFERRABLITY"
 
6006
#endif /* ODBCVER */
 
6007
                "\n from"
 
6008
                "\n (select conrelid, conkey, confrelid, confkey"
 
6009
                ",\n     generate_series(array_lower(conkey, 1), array_upper(conkey, 1)) as i"
 
6010
                ",\n     confupdtype, confdeltype, conname"
 
6011
                ",\n     condeferrable, condeferred"
 
6012
                "\n  from pg_catalog.pg_constraint cn"
 
6013
                ",\n    pg_catalog.pg_class c"
 
6014
                "\n  where contype = 'f' %s"
 
6015
                "\n   and  relname %s'%s'"
 
6016
                "\n ) ref"
 
6017
                ",\n pg_catalog.pg_class c1"
 
6018
                ",\n pg_catalog.pg_attribute a1"
 
6019
                ",\n pg_catalog.pg_class c2"
 
6020
                ",\n pg_catalog.pg_attribute a2"
 
6021
                "\n where c1.oid = ref.conrelid"
 
6022
                "\n  and  c2.oid = ref.confrelid"
 
6023
                "\n  and  a1.attrelid = c1.oid"
 
6024
                "\n  and  a1.attnum = conkey[i]"
 
6025
                "\n  and  a2.attrelid = c2.oid"
 
6026
                "\n  and  a2.attnum = confkey[i]"
 
6027
                "\n  order by ref.oid, ref.i"
 
6028
                , catName
 
6029
                , scmName1
 
6030
                , catName
 
6031
                , scmName2
 
6032
                , SQL_CASCADE
 
6033
                , SQL_SET_NULL
 
6034
                , SQL_SET_DEFAULT
 
6035
                , SQL_RESTRICT
 
6036
                , SQL_NO_ACTION
 
6037
                , SQL_CASCADE
 
6038
                , SQL_SET_NULL
 
6039
                , SQL_SET_DEFAULT
 
6040
                , SQL_RESTRICT
 
6041
                , SQL_NO_ACTION
 
6042
#if (ODBCVER >= 0x0300)
 
6043
                , SQL_INITIALLY_DEFERRED
 
6044
                , SQL_INITIALLY_IMMEDIATE
 
6045
                , SQL_NOT_DEFERRABLE
 
6046
#endif /* ODBCVER */
 
6047
                , relqual, eq_string, escTableName);
 
6048
        }
 
6049
 
 
6050
        if (res = CC_send_query(conn, tables_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
 
6051
        {
 
6052
                SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ForeignKeys query error", func);
 
6053
                QR_Destructor(res);
 
6054
                goto cleanup;
 
6055
        }
 
6056
        SC_set_Result(stmt, res);
 
6057
        ret = SQL_SUCCESS;
 
6058
 
 
6059
cleanup:
 
6060
#undef  return
 
6061
 
 
6062
        /*
 
6063
         * also, things need to think that this statement is finished so the
 
6064
         * results can be retrieved.
 
6065
         */
 
6066
        if (SQL_SUCCEEDED(ret))
 
6067
        {
 
6068
                stmt->status = STMT_FINISHED;
 
6069
                extend_column_bindings(SC_get_ARDF(stmt), QR_NumResultCols(res));
 
6070
        }
 
6071
        if (pk_table_needed)
 
6072
                free(pk_table_needed);
 
6073
        if (escTableName)
 
6074
                free(escTableName);
 
6075
        if (fk_table_needed)
 
6076
                free(fk_table_needed);
 
6077
        /* set up the current tuple pointer for SQLFetch */
 
6078
        stmt->currTuple = -1;
 
6079
        SC_set_rowset_start(stmt, -1, FALSE);
 
6080
        SC_set_current_col(stmt, -1);
 
6081
 
 
6082
        if (stmt->internal)
 
6083
                ret = DiscardStatementSvp(stmt, ret, FALSE);
 
6084
        mylog("%s(): EXIT, stmt=%p, ret=%d\n", func, stmt, ret);
 
6085
        return ret;
 
6086
}