@@ -418,7 +418,7 @@ RETCODE result;
418418break ;
419419
420420case SQL_ORDER_BY_COLUMNS_IN_SELECT :/* ODBC 2.0 */
421- p = "Y" ;
421+ p = ( PROTOCOL_62 ( ci ) || PROTOCOL_63 ( ci )) ? "Y" : "N" ;
422422break ;
423423
424424case SQL_OUTER_JOINS :/* ODBC 1.0 */
@@ -1181,7 +1181,7 @@ RETCODE result;
11811181char table_owner [MAX_INFO_STRING ],table_name [MAX_INFO_STRING ],field_name [MAX_INFO_STRING ],field_type_name [MAX_INFO_STRING ];
11821182Int2 field_number ,result_cols ;
11831183Int4 field_type ,the_type ,field_length ,mod_length ;
1184- char not_null [MAX_INFO_STRING ];
1184+ char not_null [MAX_INFO_STRING ], relhasrules [ MAX_INFO_STRING ] ;
11851185ConnInfo * ci ;
11861186
11871187
@@ -1200,7 +1200,8 @@ ConnInfo *ci;
12001200// **********************************************************************
12011201//Create the query to find out the columns (Note: pre 6.3 did not have the atttypmod field)
12021202// **********************************************************************
1203- sprintf (columns_query ,"select u.usename, c.relname, a.attname, a.atttypid,t.typname, a.attnum, a.attlen, %s, a.attnotnull from pg_user u, pg_class c, pg_attribute a, pg_type t where "
1203+ sprintf (columns_query ,"select u.usename, c.relname, a.attname, a.atttypid,t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules "
1204+ "from pg_user u, pg_class c, pg_attribute a, pg_type t where "
12041205"int4out(u.usesysid) = int4out(c.relowner) and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0)" ,
12051206PROTOCOL_62 (ci ) ?"a.attlen" :"a.atttypmod" );
12061207
@@ -1324,6 +1325,16 @@ ConnInfo *ci;
13241325return SQL_ERROR ;
13251326 }
13261327
1328+ result = SQLBindCol (hcol_stmt ,10 ,SQL_C_CHAR ,
1329+ relhasrules ,MAX_INFO_STRING ,NULL );
1330+ if ((result != SQL_SUCCESS )&& (result != SQL_SUCCESS_WITH_INFO )) {
1331+ stmt -> errormsg = col_stmt -> errormsg ;
1332+ stmt -> errornumber = col_stmt -> errornumber ;
1333+ SC_log_error (func ,"" ,stmt );
1334+ SQLFreeStmt (hcol_stmt ,SQL_DROP );
1335+ return SQL_ERROR ;
1336+ }
1337+
13271338stmt -> result = QR_Constructor ();
13281339if (!stmt -> result ) {
13291340stmt -> errormsg = "Couldn't allocate memory for SQLColumns result." ;
@@ -1368,7 +1379,9 @@ ConnInfo *ci;
13681379
13691380if (result != SQL_ERROR && !stmt -> internal ) {
13701381
1371- if (atoi (ci -> show_oid_column )|| strncmp (table_name ,POSTGRES_SYS_PREFIX ,strlen (POSTGRES_SYS_PREFIX ))== 0 ) {
1382+ if (relhasrules [0 ]!= '1' &&
1383+ (atoi (ci -> show_oid_column )||
1384+ strncmp (table_name ,POSTGRES_SYS_PREFIX ,strlen (POSTGRES_SYS_PREFIX ))== 0 )) {
13721385
13731386/*For OID fields */
13741387the_type = PG_TYPE_OID ;
@@ -1466,7 +1479,7 @@ ConnInfo *ci;
14661479
14671480//Put the row version column at the end so it might not be
14681481//mistaken for a key field.
1469- if ( !stmt -> internal && atoi (ci -> row_versioning )) {
1482+ if (relhasrules [ 0 ] != '1' && !stmt -> internal && atoi (ci -> row_versioning )) {
14701483/*For Row Versioning fields */
14711484the_type = PG_TYPE_INT4 ;
14721485
@@ -1521,6 +1534,12 @@ static char *func = "SQLSpecialColumns";
15211534TupleNode * row ;
15221535StatementClass * stmt = (StatementClass * )hstmt ;
15231536ConnInfo * ci ;
1537+ HSTMT hcol_stmt ;
1538+ StatementClass * col_stmt ;
1539+ char columns_query [MAX_STATEMENT_LEN ];
1540+ RETCODE result ;
1541+ char relhasrules [MAX_INFO_STRING ];
1542+
15241543
15251544
15261545mylog ("%s: entering...stmt=%u\n" ,func ,stmt );
@@ -1532,6 +1551,53 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
15321551ci = & stmt -> hdbc -> connInfo ;
15331552
15341553stmt -> manual_result = TRUE;
1554+
1555+
1556+ // **********************************************************************
1557+ //Create the query to find out if this is a view or not...
1558+ // **********************************************************************
1559+ sprintf (columns_query ,"select c.relhasrules "
1560+ "from pg_user u, pg_class c where "
1561+ "int4out(u.usesysid) = int4out(c.relowner) " );
1562+
1563+ my_strcat (columns_query ," and c.relname like '%.*s'" ,szTableName ,cbTableName );
1564+ my_strcat (columns_query ," and u.usename like '%.*s'" ,szTableOwner ,cbTableOwner );
1565+
1566+
1567+ result = SQLAllocStmt (stmt -> hdbc ,& hcol_stmt );
1568+ if ((result != SQL_SUCCESS )&& (result != SQL_SUCCESS_WITH_INFO )) {
1569+ stmt -> errornumber = STMT_NO_MEMORY_ERROR ;
1570+ stmt -> errormsg = "Couldn't allocate statement for SQLSpecialColumns result." ;
1571+ SC_log_error (func ,"" ,stmt );
1572+ return SQL_ERROR ;
1573+ }
1574+ col_stmt = (StatementClass * )hcol_stmt ;
1575+
1576+ mylog ("SQLSpecialColumns: hcol_stmt = %u, col_stmt = %u\n" ,hcol_stmt ,col_stmt );
1577+
1578+ result = SQLExecDirect (hcol_stmt ,columns_query ,
1579+ strlen (columns_query ));
1580+ if ((result != SQL_SUCCESS )&& (result != SQL_SUCCESS_WITH_INFO )) {
1581+ stmt -> errormsg = SC_create_errormsg (hcol_stmt );
1582+ stmt -> errornumber = col_stmt -> errornumber ;
1583+ SC_log_error (func ,"" ,stmt );
1584+ SQLFreeStmt (hcol_stmt ,SQL_DROP );
1585+ return SQL_ERROR ;
1586+ }
1587+
1588+ result = SQLBindCol (hcol_stmt ,1 ,SQL_C_CHAR ,
1589+ relhasrules ,MAX_INFO_STRING ,NULL );
1590+ if ((result != SQL_SUCCESS )&& (result != SQL_SUCCESS_WITH_INFO )) {
1591+ stmt -> errormsg = col_stmt -> errormsg ;
1592+ stmt -> errornumber = col_stmt -> errornumber ;
1593+ SC_log_error (func ,"" ,stmt );
1594+ SQLFreeStmt (hcol_stmt ,SQL_DROP );
1595+ return SQL_ERROR ;
1596+ }
1597+
1598+ result = SQLFetch (hcol_stmt );
1599+ SQLFreeStmt (hcol_stmt ,SQL_DROP );
1600+
15351601stmt -> result = QR_Constructor ();
15361602extend_bindings (stmt ,8 );
15371603
@@ -1545,40 +1611,45 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
15451611QR_set_field_info (stmt -> result ,6 ,"SCALE" ,PG_TYPE_INT2 ,2 );
15461612QR_set_field_info (stmt -> result ,7 ,"PSEUDO_COLUMN" ,PG_TYPE_INT2 ,2 );
15471613
1548- /* use the oid value for the rowid */
1549- if (fColType == SQL_BEST_ROWID ) {
1550- row = (TupleNode * )malloc (sizeof (TupleNode )+ (8 - 1 )* sizeof (TupleField ));
1614+ if (relhasrules [0 ]!= '1' ) {
1615+ /* use the oid value for the rowid */
1616+ if (fColType == SQL_BEST_ROWID ) {
1617+ row = (TupleNode * )malloc (sizeof (TupleNode )+ (8 - 1 )* sizeof (TupleField ));
15511618
1552- set_tuplefield_int2 (& row -> tuple [0 ],SQL_SCOPE_SESSION );
1553- set_tuplefield_string (& row -> tuple [1 ],"oid" );
1554- set_tuplefield_int2 (& row -> tuple [2 ],pgtype_to_sqltype (stmt ,PG_TYPE_OID ));
1555- set_tuplefield_string (& row -> tuple [3 ],"OID" );
1556- set_tuplefield_int4 (& row -> tuple [4 ],pgtype_precision (stmt ,PG_TYPE_OID ,PG_STATIC ,PG_STATIC ));
1557- set_tuplefield_int4 (& row -> tuple [5 ],pgtype_length (stmt ,PG_TYPE_OID ,PG_STATIC ,PG_STATIC ));
1558- set_tuplefield_int2 (& row -> tuple [6 ],pgtype_scale (stmt ,PG_TYPE_OID ));
1559- set_tuplefield_int2 (& row -> tuple [7 ],SQL_PC_PSEUDO );
1619+ set_tuplefield_int2 (& row -> tuple [0 ],SQL_SCOPE_SESSION );
1620+ set_tuplefield_string (& row -> tuple [1 ],"oid" );
1621+ set_tuplefield_int2 (& row -> tuple [2 ],pgtype_to_sqltype (stmt ,PG_TYPE_OID ));
1622+ set_tuplefield_string (& row -> tuple [3 ],"OID" );
1623+ set_tuplefield_int4 (& row -> tuple [4 ],pgtype_precision (stmt ,PG_TYPE_OID ,PG_STATIC ,PG_STATIC ));
1624+ set_tuplefield_int4 (& row -> tuple [5 ],pgtype_length (stmt ,PG_TYPE_OID ,PG_STATIC ,PG_STATIC ));
1625+ set_tuplefield_int2 (& row -> tuple [6 ],pgtype_scale (stmt ,PG_TYPE_OID ));
1626+ set_tuplefield_int2 (& row -> tuple [7 ],SQL_PC_PSEUDO );
15601627
1561- QR_add_tuple (stmt -> result ,row );
1628+ QR_add_tuple (stmt -> result ,row );
15621629
1563- }else if (fColType == SQL_ROWVER ) {
1630+ }else if (fColType == SQL_ROWVER ) {
15641631
1565- Int2 the_type = PG_TYPE_INT4 ;
1632+ Int2 the_type = PG_TYPE_INT4 ;
15661633
1567- if (atoi (ci -> row_versioning )) {
1568- row = (TupleNode * )malloc (sizeof (TupleNode )+ (8 - 1 )* sizeof (TupleField ));
1634+ if (atoi (ci -> row_versioning )) {
1635+ row = (TupleNode * )malloc (sizeof (TupleNode )+ (8 - 1 )* sizeof (TupleField ));
15691636
1570- set_tuplefield_null (& row -> tuple [0 ]);
1571- set_tuplefield_string (& row -> tuple [1 ],"xmin" );
1572- set_tuplefield_int2 (& row -> tuple [2 ],pgtype_to_sqltype (stmt ,the_type ));
1573- set_tuplefield_string (& row -> tuple [3 ],pgtype_to_name (stmt ,the_type ));
1574- set_tuplefield_int4 (& row -> tuple [4 ],pgtype_precision (stmt ,the_type ,PG_STATIC ,PG_STATIC ));
1575- set_tuplefield_int4 (& row -> tuple [5 ],pgtype_length (stmt ,the_type ,PG_STATIC ,PG_STATIC ));
1576- set_tuplefield_int2 (& row -> tuple [6 ],pgtype_scale (stmt ,the_type ));
1577- set_tuplefield_int2 (& row -> tuple [7 ],SQL_PC_PSEUDO );
1637+ set_tuplefield_null (& row -> tuple [0 ]);
1638+ set_tuplefield_string (& row -> tuple [1 ],"xmin" );
1639+ set_tuplefield_int2 (& row -> tuple [2 ],pgtype_to_sqltype (stmt ,the_type ));
1640+ set_tuplefield_string (& row -> tuple [3 ],pgtype_to_name (stmt ,the_type ));
1641+ set_tuplefield_int4 (& row -> tuple [4 ],pgtype_precision (stmt ,the_type ,PG_STATIC ,PG_STATIC ));
1642+ set_tuplefield_int4 (& row -> tuple [5 ],pgtype_length (stmt ,the_type ,PG_STATIC ,PG_STATIC ));
1643+ set_tuplefield_int2 (& row -> tuple [6 ],pgtype_scale (stmt ,the_type ));
1644+ set_tuplefield_int2 (& row -> tuple [7 ],SQL_PC_PSEUDO );
15781645
1579- QR_add_tuple (stmt -> result ,row );
1646+ QR_add_tuple (stmt -> result ,row );
1647+ }
15801648}
15811649}
1650+
1651+
1652+
15821653stmt -> status = STMT_FINISHED ;
15831654stmt -> currTuple = -1 ;
15841655stmt -> rowset_start = -1 ;
@@ -1613,7 +1684,7 @@ TupleNode *row;
16131684int i ;
16141685HSTMT hcol_stmt ;
16151686StatementClass * col_stmt ,* indx_stmt ;
1616- char column_name [MAX_INFO_STRING ];
1687+ char column_name [MAX_INFO_STRING ], relhasrules [ MAX_INFO_STRING ] ;
16171688char * * column_names = 0 ;
16181689Int4 column_name_len ;
16191690int total_columns = 0 ;
@@ -1742,7 +1813,7 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
17421813 }
17431814indx_stmt = (StatementClass * )hindx_stmt ;
17441815
1745- sprintf (index_query ,"select c.relname, i.indkey, i.indisunique, i.indisclustered from pg_index i, pg_class c, pg_class d where c.oid = i.indexrelid and d.relname = '%s' and d.oid = i.indrelid" ,
1816+ sprintf (index_query ,"select c.relname, i.indkey, i.indisunique, i.indisclustered, c.relhasrules from pg_index i, pg_class c, pg_class d where c.oid = i.indexrelid and d.relname = '%s' and d.oid = i.indrelid" ,
17461817table_name );
17471818
17481819result = SQLExecDirect (hindx_stmt ,index_query ,strlen (index_query ));
@@ -1795,8 +1866,17 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
17951866
17961867 }
17971868
1869+ result = SQLBindCol (hindx_stmt ,5 ,SQL_C_CHAR ,
1870+ relhasrules ,MAX_INFO_STRING ,NULL );
1871+ if ((result != SQL_SUCCESS )&& (result != SQL_SUCCESS_WITH_INFO )) {
1872+ stmt -> errormsg = indx_stmt -> errormsg ;
1873+ stmt -> errornumber = indx_stmt -> errornumber ;
1874+ SQLFreeStmt (hindx_stmt ,SQL_DROP );
1875+ gotoSEEYA ;
1876+ }
1877+
17981878/*fake index of OID */
1799- if (atoi (ci -> show_oid_column )&& atoi (ci -> fake_oid_index )) {
1879+ if (relhasrules [ 0 ] != '1' && atoi (ci -> show_oid_column )&& atoi (ci -> fake_oid_index )) {
18001880row = (TupleNode * )malloc (sizeof (TupleNode )+
18011881 (13 - 1 )* sizeof (TupleField ));
18021882