📄 info.c
字号:
} stmt->status = STMT_FINISHED; stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; mylog("SQLSpecialColumns(): EXIT, stmt=%u\n", stmt); return SQL_SUCCESS;}RETCODE SQL_API SQLStatistics( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UWORD fUnique, UWORD fAccuracy){static char *func="SQLStatistics";StatementClass *stmt = (StatementClass *) hstmt;char index_query[MAX_STATEMENT_LEN];HSTMT hindx_stmt;RETCODE result;char *table_name;char index_name[MAX_INFO_STRING];short fields_vector[8];char isunique[10], isclustered[10];SDWORD index_name_len, fields_vector_len;TupleNode *row;int i;HSTMT hcol_stmt;StatementClass *col_stmt, *indx_stmt;char column_name[MAX_INFO_STRING];char **column_names = 0;Int4 column_name_len;int total_columns = 0;char error = TRUE;ConnInfo *ci;char buf[256];mylog("%s: entering...stmt=%u\n", func, stmt); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt->manual_result = TRUE; stmt->errormsg_created = TRUE; ci = &stmt->hdbc->connInfo; stmt->result = QR_Constructor(); if(!stmt->result) { stmt->errormsg = "Couldn't allocate memory for SQLStatistics result."; stmt->errornumber = STMT_NO_MEMORY_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; } // the binding structure for a statement is not set up until // a statement is actually executed, so we'll have to do this ourselves. extend_bindings(stmt, 13); // set the field names QR_set_num_fields(stmt->result, 13); QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 3, "NON_UNIQUE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 4, "INDEX_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 5, "INDEX_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 6, "TYPE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 7, "SEQ_IN_INDEX", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 8, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 9, "COLLATION", PG_TYPE_CHAR, 1); QR_set_field_info(stmt->result, 10, "CARDINALITY", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 11, "PAGES", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 12, "FILTER_CONDITION", PG_TYPE_TEXT, MAX_INFO_STRING); // only use the table name... the owner should be redundant, and // we never use qualifiers. table_name = make_string(szTableName, cbTableName, NULL); if ( ! table_name) { stmt->errormsg = "No table name passed to SQLStatistics."; stmt->errornumber = STMT_INTERNAL_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; } // we need to get a list of the field names first, // so we can return them later. result = SQLAllocStmt( stmt->hdbc, &hcol_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = "SQLAllocStmt failed in SQLStatistics for columns."; stmt->errornumber = STMT_NO_MEMORY_ERROR; goto SEEYA; } col_stmt = (StatementClass *) hcol_stmt; /* "internal" prevents SQLColumns from returning the oid if it is being shown. This would throw everything off. */ col_stmt->internal = TRUE; result = SQLColumns(hcol_stmt, "", 0, "", 0, table_name, (SWORD) strlen(table_name), "", 0); col_stmt->internal = FALSE; if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; // "SQLColumns failed in SQLStatistics."; stmt->errornumber = col_stmt->errornumber; // STMT_EXEC_ERROR; SQLFreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } result = SQLBindCol(hcol_stmt, 4, SQL_C_CHAR, column_name, MAX_INFO_STRING, &column_name_len); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SQLFreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } result = SQLFetch(hcol_stmt); while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { total_columns++; column_names = (char **)realloc(column_names, total_columns * sizeof(char *)); column_names[total_columns-1] = (char *)malloc(strlen(column_name)+1); strcpy(column_names[total_columns-1], column_name); mylog("SQLStatistics: column_name = '%s'\n", column_name); result = SQLFetch(hcol_stmt); } if(result != SQL_NO_DATA_FOUND || total_columns == 0) { stmt->errormsg = SC_create_errormsg(hcol_stmt); // "Couldn't get column names in SQLStatistics."; stmt->errornumber = col_stmt->errornumber; SQLFreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } SQLFreeStmt(hcol_stmt, SQL_DROP); // get a list of indexes on this table result = SQLAllocStmt( stmt->hdbc, &hindx_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = "SQLAllocStmt failed in SQLStatistics for indices."; stmt->errornumber = STMT_NO_MEMORY_ERROR; goto SEEYA; } indx_stmt = (StatementClass *) hindx_stmt; 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", table_name); result = SQLExecDirect(hindx_stmt, index_query, strlen(index_query)); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = SC_create_errormsg(hindx_stmt); // "Couldn't execute index query (w/SQLExecDirect) in SQLStatistics."; stmt->errornumber = indx_stmt->errornumber; SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } // bind the index name column result = SQLBindCol(hindx_stmt, 1, SQL_C_CHAR, index_name, MAX_INFO_STRING, &index_name_len); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; // "Couldn't bind column in SQLStatistics."; stmt->errornumber = indx_stmt->errornumber; SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } // bind the vector column result = SQLBindCol(hindx_stmt, 2, SQL_C_DEFAULT, fields_vector, 16, &fields_vector_len); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; // "Couldn't bind column in SQLStatistics."; stmt->errornumber = indx_stmt->errornumber; SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } // bind the "is unique" column result = SQLBindCol(hindx_stmt, 3, SQL_C_CHAR, isunique, sizeof(isunique), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; // "Couldn't bind column in SQLStatistics."; stmt->errornumber = indx_stmt->errornumber; SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } // bind the "is clustered" column result = SQLBindCol(hindx_stmt, 4, SQL_C_CHAR, isclustered, sizeof(isclustered), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; // "Couldn't bind column in SQLStatistics."; stmt->errornumber = indx_stmt->errornumber; SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* fake index of OID */ if (atoi(ci->show_oid_column) && atoi(ci->fake_oid_index)) { row = (TupleNode *)malloc(sizeof(TupleNode) + (13 - 1) * sizeof(TupleField)); // no table qualifier set_tuplefield_string(&row->tuple[0], ""); // don't set the table owner, else Access tries to use it set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); // non-unique index? set_tuplefield_int2(&row->tuple[3], (Int2) (globals.unique_index ? FALSE : TRUE)); // no index qualifier set_tuplefield_string(&row->tuple[4], ""); sprintf(buf, "%s_idx_fake_oid", table_name); set_tuplefield_string(&row->tuple[5], buf); // Clustered index? I think non-clustered should be type OTHER not HASHED set_tuplefield_int2(&row->tuple[6], (Int2) SQL_INDEX_OTHER); set_tuplefield_int2(&row->tuple[7], (Int2) 1); set_tuplefield_string(&row->tuple[8], "oid"); set_tuplefield_string(&row->tuple[9], "A"); set_tuplefield_null(&row->tuple[10]); set_tuplefield_null(&row->tuple[11]); set_tuplefield_null(&row->tuple[12]); QR_add_tuple(stmt->result, row); } result = SQLFetch(hindx_stmt); while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { // If only requesting unique indexs, then just return those. if (fUnique == SQL_INDEX_ALL || (fUnique == SQL_INDEX_UNIQUE && atoi(isunique))) { i = 0; // add a row in this table for each field in the index while(i < 8 && fields_vector[i] != 0) { row = (TupleNode *)malloc(sizeof(TupleNode) + (13 - 1) * sizeof(TupleField)); // no table qualifier set_tuplefield_string(&row->tuple[0], ""); // don't set the table owner, else Access tries to use it set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); // non-unique index? if (globals.unique_index) set_tuplefield_int2(&row->tuple[3], (Int2) (atoi(isunique) ? FALSE : TRUE)); else set_tuplefield_int2(&row->tuple[3], TRUE); // no index qualifier set_tuplefield_string(&row->tuple[4], ""); set_tuplefield_string(&row->tuple[5], index_name); // Clustered index? I think non-clustered should be type OTHER not HASHED set_tuplefield_int2(&row->tuple[6], (Int2) (atoi(isclustered) ? SQL_INDEX_CLUSTERED : SQL_INDEX_OTHER)); set_tuplefield_int2(&row->tuple[7], (Int2) (i+1)); if(fields_vector[i] == OID_ATTNUM) { set_tuplefield_string(&row->tuple[8], "oid"); mylog("SQLStatistics: column name = oid\n"); } else if(fields_vector[i] < 0 || fields_vector[i] > total_columns) { set_tuplefield_string(&row->tuple[8], "UNKNOWN"); mylog("SQLStatistics: column name = UNKNOWN\n"); } else { set_tuplefield_string(&row->tuple[8], column_names[fields_vector[i]-1]); mylog("SQLStatistics: column name = '%s'\n", column_names[fields_vector[i]-1]); } set_tuplefield_string(&row->tuple[9], "A"); set_tuplefield_null(&row->tuple[10]); set_tuplefield_null(&row->tuple[11]); set_tuplefield_null(&row->tuple[12]); QR_add_tuple(stmt->result, row); i++; } } result = SQLFetch(hindx_stmt); } if(result != SQL_NO_DATA_FOUND) { stmt->errormsg = SC_create_errormsg(hindx_stmt); // "SQLFetch failed in SQLStatistics."; stmt->errornumber = indx_stmt->errornumber; SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } SQLFreeStmt(hindx_stmt, SQL_DROP); // also, things need to think that this statement is finished so // the results can be retrieved. stmt->status = STMT_FINISHED; // set up the current tuple pointer for SQLFetch stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; error = FALSE;SEEYA: /* These things should be freed on any error ALSO! */ free(table_name); for(i = 0; i < total_columns; i++) { free(column_names[i]); } free(column_names); mylog("SQLStatistics(): EXIT, %s, stmt=%u\n", error ? "error" : "success", stmt); if (error) { SC_log_error(func, "", stmt); return SQL_ERROR; } else return SQL_SUCCESS;}RETCODE SQL_API SQLColumnPrivileges( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UCHAR FAR * szColumnName, SWORD cbColumnName){static char *func="SQLColumnPrivileges"; mylog("%s: entering...\n", func);/* Neither Access or Borland care about this. */ SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR;}RETCODE SQL_API SQLPrimaryKeys( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName){static char *func = "SQLPrimaryKeys";StatementClass *stmt = (StatementClass *) hstmt;TupleNode *row;RETCODE result;int seq = 0;HSTMT htbl_stmt;StatementClass *tbl_stmt;char tables_query[MAX_STATEMENT_LEN];char attname[MAX_INFO_STRING];SDWORD attname_len;char pktab[MAX_TABLE_LEN + 1];Int2 result_cols; mylog("%s: entering...stmt=%u\n", f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -