@@ -2902,6 +2902,52 @@ MYLOG(0, " and the data=%s\n", attdef);
2902
2902
return ret ;
2903
2903
}
2904
2904
2905
+ /** @brief Retrieve the primary or unique key columns for the specified table
2906
+ *
2907
+ * @param conn ConnectionClass
2908
+ * @param stmt StatementClass
2909
+ * @param szTableName Table name
2910
+ * @param szTableQualifier Schema name
2911
+ * @param szSchemaName Schema name
2912
+ * @return QResultClass
2913
+ */
2914
+ static QResultClass *
2915
+ findPrimaryOrUnique (ConnectionClass * conn , StatementClass * stmt , const SQLCHAR * szTableName , const SQLCHAR * szTableQualifier , const SQLCHAR * szSchemaName , bool primaryOrUnique ) {
2916
+ PQExpBufferData columns_query = {0 };
2917
+
2918
+ initPQExpBuffer (& columns_query );
2919
+ printfPQExpBuffer (& columns_query , "select NULL as \"SCOPE\","
2920
+ "a.attname AS \"COLUMN_NAME\","
2921
+ "t.typname AS \"DATA_TYPE\","
2922
+ "t.typname AS \"TYPE_NAME\","
2923
+ "t.typlen AS \"COLUMN_SIZE\","
2924
+ "a.attlen AS \"BUFFER_LENGTH\","
2925
+ "case "
2926
+ "when t.typname = 'numeric' then"
2927
+ " case when a.atttypmod > -1 then 6"
2928
+ " else a.atttypmod::int4"
2929
+ " end"
2930
+ " else 0"
2931
+ " end AS \"DECIMAL_DIGITS\","
2932
+ "1 AS \"PSEUDO_COLUMN\" "
2933
+ "FROM pg_class c "
2934
+ "INNER JOIN pg_namespace n ON n.oid = c.relnamespace "
2935
+ "INNER JOIN pg_attribute a ON a.attrelid = c.oid "
2936
+ "INNER JOIN pg_type t on a.atttypid = t.oid "
2937
+ "LEFT JOIN pg_index i ON i.indrelid = c.oid "
2938
+ "AND a.attnum = ANY (i.indkey[0:(i.indnkeyatts - 1)]) " );
2939
+ if (primaryOrUnique ) {
2940
+ appendPQExpBuffer (& columns_query , "WHERE i.indisprimary and a.attnum > 0 and c.relname='%s'" , szTableName );
2941
+ } else {
2942
+ appendPQExpBuffer (& columns_query , "WHERE i.indisunique and a.attnum > 0 and c.relname ='%s'" , szTableName );
2943
+ }
2944
+
2945
+
2946
+ if (szTableQualifier != NULL )
2947
+ appendPQExpBuffer (& columns_query , " and n.nspname = '%s'" , szSchemaName );
2948
+
2949
+ return CC_send_query (conn , columns_query .data , NULL , READ_ONLY_QUERY , stmt );
2950
+ }
2905
2951
2906
2952
/** @brief Retrieve the optimal set of columns that uniquely identifies a row in the specified table (when IdentifierType is SQL_BEST_ROWID)
2907
2953
* The columns that are automatically updated when any value in the row is updated (when IdentifierType is SQL_ROWVER)
@@ -3146,57 +3192,25 @@ PGAPI_SpecialColumns(HSTMT hstmt,
3146
3192
set_tuplefield_int4 (& tuple [SPECOLS_BUFFER_LENGTH ], PGTYPE_ATTR_BUFFER_LENGTH (conn , the_type , atttypmod ));
3147
3193
set_tuplefield_int2 (& tuple [SPECOLS_DECIMAL_DIGITS ], PGTYPE_ATTR_DECIMAL_DIGITS (conn , the_type , atttypmod ));
3148
3194
set_tuplefield_int2 (& tuple [SPECOLS_PSEUDO_COLUMN ], SQL_PC_PSEUDO );
3149
- } else {
3150
- /*
3151
-
3152
- SELECT NULL as \"SCOPE\",
3153
- n.nspname AS \"SCHEMA_NAME\"",
3154
- c.relname AS \"TABLE_NAME\"",
3155
- a.attname AS \"COLUMN_NAME\"",
3156
- t.typname AS \"DATA_TYPE\",
3157
- t.typename AS \"TYPE_NAME\"",
3158
- i.indisunique,i.indisprimary
3159
- FROM pg_class c
3160
- INNER JOIN pg_namespace n ON n.oid = c.relnamespace
3161
- INNER JOIN pg_attribute a ON a.attrelid = c.oid
3162
- INNER JOIN pg_type t on a.atttypid = t.oid
3163
- LEFT JOIN pg_index i
3164
- ON i.indrelid = c.oid
3165
- AND a.attnum = ANY (i.indkey[0:(i.indnkeyatts - 1)])
3166
- WHERE a.attnum > 0 and c.relname like 'testuktab';
3167
- */
3168
- initPQExpBuffer (& columns_query );
3169
- printfPQExpBuffer (& columns_query , "select NULL as \"SCOPE\","
3170
- "a.attname AS \"COLUMN_NAME\","
3171
- "t.typname AS \"DATA_TYPE\","
3172
- "t.typname AS \"TYPE_NAME\","
3173
- "t.typlen AS \"COLUMN_SIZE\","
3174
- "a.attlen AS \"BUFFER_LENGTH\","
3175
- "case "
3176
- "when t.typname = 'numeric' then"
3177
- " case when a.atttypmod > -1 then 6"
3178
- " else a.atttypmod::int4"
3179
- " end"
3180
- " else 0"
3181
- " end AS \"DECIMAL_DIGITS\","
3182
- "1 AS \"PSEUDO_COLUMN\" "
3183
- "FROM pg_class c "
3184
- "INNER JOIN pg_namespace n ON n.oid = c.relnamespace "
3185
- "INNER JOIN pg_attribute a ON a.attrelid = c.oid "
3186
- "INNER JOIN pg_type t on a.atttypid = t.oid "
3187
- "LEFT JOIN pg_index i ON i.indrelid = c.oid "
3188
- "AND a.attnum = ANY (i.indkey[0:(i.indnkeyatts - 1)]) "
3189
- "WHERE i.indisunique and a.attnum > 0 and c.relname ='%s'" , szTableName );
3190
-
3191
-
3192
- if (szTableQualifier != NULL )
3193
- appendPQExpBuffer (& columns_query , " and c.relnamespace = %s" , szSchemaName );
3194
-
3195
- if (res = CC_send_query (conn , columns_query .data , NULL , READ_ONLY_QUERY , stmt ), !QR_command_maybe_successful (res ))
3195
+ } else {
3196
+ // look for primary first
3197
+ res = findPrimaryOrUnique (conn , stmt , szTableName , szTableQualifier , szSchemaName , TRUE);
3198
+ if (!QR_command_maybe_successful (res ))
3196
3199
{
3197
3200
SC_set_error (stmt , STMT_EXEC_ERROR , "PGAPI_Special query error" , func );
3198
3201
goto cleanup ;
3199
3202
}
3203
+ if (0 == QR_get_num_total_tuples (res ))
3204
+ {
3205
+ // didn't find primary now look for uniaue
3206
+ res = findPrimaryOrUnique (conn , stmt , szTableName , szTableName , szSchemaName , FALSE);
3207
+ if (!QR_command_maybe_successful (res ))
3208
+ {
3209
+ SC_set_error (stmt , STMT_EXEC_ERROR , "PGAPI_Special query error" , func );
3210
+ goto cleanup ;
3211
+ }
3212
+ }
3213
+
3200
3214
SC_set_Result (stmt , res );
3201
3215
}
3202
3216
}
0 commit comments