catalog.c
上传用户:jmzj888
上传日期:2007-01-02
资源大小:220k
文件大小:24k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
  2.    This file is public domain and comes with NO WARRANTY of any kind */
  3. /*
  4. ** CATALOG.C - This is the ODBC sample driver code for
  5. ** executing Data Dictionary functions.
  6. */
  7. #include "myodbc.h"
  8. static MYSQL_ROW fix_fields_copy(STMT FAR *hstmt,MYSQL_ROW row);
  9. static int check_parameters(HSTMT hstmt,UCHAR FAR *szTableQualifier,
  10.     SWORD cbTableQualifier,UCHAR FAR *szTableOwner,
  11.     SWORD cbTableOwner,UCHAR FAR *szTableName,SWORD *cbTableName,
  12.     char *table_name,bool no_wildcards);
  13. //  Have DBMS set up result set of Tables.
  14. uint SQLTABLES_order[]={2};
  15. char *SQLTABLES_values[]={"","",NULL,"TABLE","MySQL table"};
  16. char *SQLTABLES_qualifier_values[]={"",NULL,NULL,NULL,NULL};
  17. char *SQLTABLES_owner_values[]={NULL,"",NULL,NULL,NULL};
  18. char *SQLTABLES_type_values[]={NULL,NULL,NULL,"TABLE",NULL};
  19. MYSQL_FIELD SQLTABLES_fields[] = {
  20.   {"Table_qualifer","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  21.   {"Table_owner","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  22.   {"Table_name","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,0},
  23.   {"Table_type","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,5,0},
  24.   {"Remarks","Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,11}};
  25. const uint SQLTABLES_FIELDS=array_elements(SQLTABLES_values);
  26. /*
  27. ** This may be changed in the future so that TableQualifier or owner points
  28. ** at different databases.
  29. */
  30. RETCODE SQL_API SQLTables(HSTMT hstmt,
  31.   UCHAR FAR *szTableQualifier,SWORD cbTableQualifier,
  32.   UCHAR FAR *szTableOwner,SWORD cbTableOwner,
  33.   UCHAR FAR *szTableName,SWORD cbTableName,
  34.   UCHAR FAR *szTableType,SWORD cbTableType)
  35. {
  36.   char Qualifier_buff[NAME_LEN+1],Owner_buff[NAME_LEN+1],Name_buff[NAME_LEN+1],
  37.        *type_buff,*TableQualifier,*TableOwner,*TableName,*TableType;
  38.   STMT FAR *stmt=(STMT FAR*) hstmt;
  39.   DBUG_ENTER("SQLTables");
  40.   DBUG_PRINT("enter",("Qualifier: '%s'  Owner: '%s'  Table: '%s'  Type: '%s'",
  41.       szTableQualifier ? szTableQualifier : "null",
  42.       szTableOwner ? szTableOwner : "null",
  43.       szTableName ? szTableName : "null",
  44.       szTableType ? szTableType : "null"));
  45.   SQLFreeStmt(hstmt,MYSQL_RESET);
  46.   if (!(type_buff=my_malloc(szTableType && cbTableType != SQL_NTS ? cbTableType+1 : 1,MYF(0))))
  47.   {
  48.     DBUG_RETURN(set_error(stmt->dbc,"S1001","Not enough memory",4001));
  49.   }
  50.   TableQualifier=fix_str((char FAR *) Qualifier_buff,szTableQualifier,
  51.  cbTableQualifier);
  52.   TableOwner=    fix_str((char FAR*) Owner_buff,szTableOwner,cbTableOwner);
  53.   TableName=     fix_str((char FAR*) Name_buff,szTableName,cbTableName);
  54.   TableType=     fix_str((char FAR*) type_buff,szTableType,cbTableType);
  55.   if (!strcmp(TableQualifier,"%") && !TableOwner[0] && !TableName[0])
  56.   {
  57.     /* Return set of allowed qualifiers */
  58.     DBUG_PRINT("info",("Return set of table qualifiers / Catalog names"));
  59.     stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
  60.     stmt->result_array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_qualifier_values,
  61.       sizeof(SQLTABLES_qualifier_values),
  62.       MYF(0));
  63.     stmt->result->row_count=1;
  64.     mysql_link_fields(stmt,SQLTABLES_fields, SQLTABLES_FIELDS);
  65.     my_free(type_buff,MYF(0));
  66.     DBUG_RETURN(SQL_SUCCESS);
  67.   }
  68.   if (!TableQualifier[0] && !strcmp(TableOwner,"%") && !TableName[0])
  69.   {
  70.     /* Return set of allowed Table owners */
  71.     DBUG_PRINT("info",("Return set of table owners / Schema names"));
  72.     stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
  73.     stmt->result_array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_owner_values,
  74.       sizeof(SQLTABLES_owner_values),
  75.       MYF(0));
  76.     stmt->result->row_count=1;
  77.     mysql_link_fields(stmt,SQLTABLES_fields, SQLTABLES_FIELDS);
  78.     my_free(type_buff,MYF(0));
  79.     DBUG_RETURN(SQL_SUCCESS);
  80.   }
  81.   if (!TableQualifier[0] && !TableOwner[0] && !TableName[0] &&
  82.       !strcmp(TableType,"%"))
  83.   {
  84.     /* Return set of TableType qualifiers */
  85.     DBUG_PRINT("info",("Return set of table types"));
  86.     stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
  87.     stmt->result_array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_type_values,
  88.       sizeof(SQLTABLES_type_values),
  89.       MYF(0));
  90.     stmt->result->row_count=1;
  91.     mysql_link_fields(stmt,SQLTABLES_fields, SQLTABLES_FIELDS);
  92.     my_free(type_buff,MYF(0));
  93.     DBUG_RETURN(SQL_SUCCESS);
  94.   }
  95.   /* Return empty set if unknown TableType or if Qualifier or Owner is used */
  96.   if ((TableType[0] && !strinstr(TableType,"TABLE")) ||
  97.       TableQualifier[0] && strcmp(TableQualifier,"%") &&
  98.       strcmp(TableQualifier,stmt->dbc->database) ||
  99.       TableOwner[0] && strcmp(TableOwner,"%") &&
  100.       strcmp(TableOwner,stmt->dbc->database))
  101.   {
  102.     DBUG_PRINT("info",("Can't match anything; Returning empty set"));
  103.     stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
  104.     stmt->result->row_count=0;
  105.     stmt->result_array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_values,
  106.       sizeof(SQLTABLES_values), MYF(0));
  107.     mysql_link_fields(stmt,SQLTABLES_fields, SQLTABLES_FIELDS);
  108.     my_free(type_buff,MYF(0));
  109.     DBUG_RETURN(SQL_SUCCESS);
  110.   }
  111.   /* This was a normal request for tables.  Return matching tables */
  112.   if (!(stmt->result=mysql_list_tables(&stmt->dbc->mysql,TableName)))
  113.   {
  114.     my_free(type_buff,MYF(0));
  115.     DBUG_RETURN(set_error(stmt->dbc,"S1000","Could not read table names",0));
  116.     DBUG_RETURN(SQL_ERROR);
  117.   }
  118.   stmt->order=       SQLTABLES_order;
  119.   stmt->order_count= array_elements(SQLTABLES_order);
  120.   stmt->fix_fields=  fix_fields_copy;
  121.   stmt->array=(MYSQL_ROW) my_memdup((gptr) SQLTABLES_values,
  122.     sizeof(SQLTABLES_values),MYF(0));
  123.   mysql_link_fields(stmt,SQLTABLES_fields,5);
  124.   my_free(type_buff,MYF(0));
  125.   DBUG_RETURN(SQL_SUCCESS);
  126. }
  127. static MYSQL_ROW fix_fields_copy(STMT FAR *stmt,MYSQL_ROW row)
  128. {
  129.   uint i;
  130.   for (i=0 ; i < stmt->order_count; i++)
  131.     stmt->array[stmt->order[i]]=row[i];
  132.   return stmt->array;
  133. }
  134. //  Have DBMS set up result set of Columns.
  135. char SC_type[10],SC_typename[20],SC_precision[10],SC_length[10],SC_scale[10],
  136.   SC_nullable[10];
  137. char *SQLCOLUMNS_values[]={"","",NULL,NULL,SC_type,SC_typename,
  138.    SC_precision,
  139.    SC_length,SC_scale,"10",SC_nullable,"MySQL column"};
  140. MYSQL_FIELD SQLCOLUMNS_fields[] = {
  141.   {"Table_cat","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  142.   {"Table_schema","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  143.   {"Table_name","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,NOT_NULL_FLAG},
  144.   {"Column_name","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,NOT_NULL_FLAG},
  145.   {"Data_type","MySQL Catalog",NULL,FIELD_TYPE_SHORT,5,5,NOT_NULL_FLAG},
  146.   {"Type_name","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,20,20,NOT_NULL_FLAG},
  147.   {"Column_size","MySQL Catalog",NULL,FIELD_TYPE_LONG,11,11},
  148.   {"Buffer_length","MySQL Catalog",NULL,FIELD_TYPE_LONG,11,11},
  149.   {"Decimal_digits","MySQL Catalog",NULL,FIELD_TYPE_SHORT,2,2},
  150.   {"Num_prec_radix","MySQL Catalog",NULL,FIELD_TYPE_SHORT,2,2},
  151.   {"Nullable","MySQL Catalog",NULL,FIELD_TYPE_SHORT,5,5,NOT_NULL_FLAG},
  152.   {"Remarks","MySQL Catalog",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN}};
  153. const uint SQLCOLUMNS_FIELDS=array_elements(SQLCOLUMNS_values);
  154. RETCODE SQL_API SQLColumns(HSTMT hstmt,
  155.    UCHAR FAR *szTableQualifier, SWORD cbTableQualifier,
  156.    UCHAR FAR *szTableOwner, SWORD cbTableOwner,
  157.    UCHAR FAR *szTableName, SWORD cbTableName,
  158.    UCHAR FAR *szColumnName, SWORD cbColumnName)
  159. {
  160.   char buff[80],table_name[NAME_LEN+1],column_name[NAME_LEN+1];
  161.   ulong transfer_length,precision,display_size;
  162.   MYSQL_FIELD *curField;
  163.   char **row;
  164.   MEM_ROOT *alloc;
  165.   STMT FAR *stmt=(STMT FAR*) hstmt;
  166.   DBUG_ENTER("SQLColumns");
  167.   if (check_parameters(hstmt,szTableQualifier,cbTableQualifier,szTableOwner,
  168.        cbTableOwner,szTableName,&cbTableName,table_name,1))
  169.     return SQL_ERROR;
  170.   if (!(stmt->result=mysql_list_fields(&stmt->dbc->mysql,table_name,
  171.        fix_str(column_name,szColumnName,
  172.        cbColumnName))))
  173.   {
  174.     strmov(stmt->dbc->sqlstate,"S1000");
  175.     DBUG_RETURN(SQL_ERROR);
  176.   }
  177.   stmt->result_array= (char**) my_malloc(sizeof(char*)*SQLCOLUMNS_FIELDS*
  178.  stmt->result->field_count,
  179.  MYF(MY_FAE | MY_ZEROFILL));
  180.   /* convert mysql fields to data that odbc wants */
  181.   alloc=&stmt->result->field_alloc;
  182.   for (row= stmt->result_array ;
  183.        (curField = mysql_fetch_field(stmt->result)) ; )
  184.   {
  185.     int type;
  186.     row[0]="";                /* No qualifers */
  187.     row[1]="";                /* No owner */
  188.     row[2]= curField->table;
  189.     row[3]= curField->name;
  190.     curField->max_length=curField->length;
  191.     type=unireg_to_sql_datatype(stmt,curField,buff,&transfer_length,&precision,&display_size);
  192.     row[5]=strdup_root(alloc,buff);
  193.     sprintf(buff,"%d",type);
  194.     row[4]=strdup_root(alloc,buff);
  195.     sprintf(buff,"%ld",precision);
  196.     row[6]=strdup_root(alloc,buff);
  197.     sprintf(buff,"%ld",transfer_length);
  198.     row[7]=strdup_root(alloc,buff);
  199.     if (IS_NUM(curField->type))
  200.     {
  201.       sprintf(buff,"%d",curField->decimals);
  202.       row[8]=strdup_root(alloc,buff); /* scale */
  203.       row[9]="10";
  204.     }
  205.     else
  206.     {
  207.        row[8]=row[9]=NullS;
  208.     }
  209.     sprintf(buff,"%d",(curField->flags & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG ?
  210.             SQL_NO_NULLS : SQL_NULLABLE);
  211.     row[10]=strdup_root(alloc,buff);
  212.     row[11]="";
  213.     row+=SQLCOLUMNS_FIELDS;
  214.   }
  215.   stmt->result->row_count=stmt->result->field_count;
  216.   mysql_link_fields(stmt,SQLCOLUMNS_fields,SQLCOLUMNS_FIELDS);
  217.   DBUG_RETURN(SQL_SUCCESS);
  218. }
  219. /* Have DBMS set up result set of Statistics. */
  220. char SS_type[10];
  221. uint SQLSTAT_order[]={2,3,5,7,8,9,10};
  222. char *SQLSTAT_values[]={NULL,NULL,"","",NULL,"",SS_type,"","","","",NULL,NULL};
  223. MYSQL_FIELD SQLSTAT_fields[] = {
  224.   {"Table_qualifer","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  225.   {"Table_owner","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  226.   {"Table_name","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,NOT_NULL_FLAG},
  227.   {"Non_unique","MySQL Stat",NULL,FIELD_TYPE_SHORT,1,1,NOT_NULL_FLAG},
  228.   {"Index_qualifer","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  229.   {"Index_name","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN},
  230.   {"Type","MySQL Stat",NULL,FIELD_TYPE_SHORT,1,1,NOT_NULL_FLAG},
  231.   {"Seq_in_index","MySQL Stat",NULL,FIELD_TYPE_SHORT,1,2,NOT_NULL_FLAG},
  232.   {"Column_name","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,NOT_NULL_FLAG},
  233.   {"Coallation","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,1,1},
  234.   {"Cardinality","MySQL Stat",NULL,FIELD_TYPE_LONG,11,11},
  235.   {"Pages","MySQL Stat",NULL,FIELD_TYPE_LONG,9,9},
  236.   {"Filter","MySQL Stat",NULL,FIELD_TYPE_VAR_STRING,10,10},
  237. };
  238. const uint SQLSTAT_FIELDS=array_elements(SQLSTAT_fields);
  239. RETCODE SQL_API SQLStatistics(HSTMT hstmt,
  240.       UCHAR FAR *szTableQualifier,
  241.       SWORD cbTableQualifier,
  242.       UCHAR FAR *szTableOwner,SWORD cbTableOwner,
  243.       UCHAR FAR *szTableName,SWORD cbTableName,
  244.       UWORD fUnique,UWORD fAccuracy)
  245. {
  246.   char buff[100],table_name[NAME_LEN+1];
  247.   STMT FAR *stmt=(STMT FAR*) hstmt;
  248.   DBUG_ENTER("SQLStatistics");
  249.   if (check_parameters(hstmt,szTableQualifier,cbTableQualifier,szTableOwner,
  250.        cbTableOwner,szTableName,&cbTableName,table_name,1))
  251.     DBUG_RETURN(SQL_ERROR);
  252.   remove_escape(table_name);
  253.   strxmov(buff,"show keys from ",table_name,NullS);
  254.   if (mysql_query(&stmt->dbc->mysql,buff) ||
  255.       !(stmt->result=mysql_store_result(&stmt->dbc->mysql)))
  256.   {
  257.     strmov(stmt->dbc->sqlstate,"S1000");
  258.     DBUG_RETURN(SQL_ERROR);
  259.   }
  260.   int2str(SQL_INDEX_OTHER,SS_type,10);
  261.   stmt->order=       SQLSTAT_order;
  262.   stmt->order_count= array_elements(SQLSTAT_order);
  263.   stmt->fix_fields=  fix_fields_copy;
  264.   stmt->array=(MYSQL_ROW) my_memdup((gptr) SQLSTAT_values,
  265.     sizeof(SQLSTAT_values),MYF(0));
  266.   if (fUnique == SQL_INDEX_UNIQUE)
  267.   { /* This is too low level... */
  268.     MYSQL_ROWS **prev,*pos;
  269.     prev= &stmt->result->data->data;
  270.     for (pos= *prev ; pos ; pos=pos->next)
  271.     {
  272.       if (pos->data[1][0] == '0') /* Unlink nonunique index */
  273.       {
  274. (*prev)=pos;
  275. prev= &pos->next;
  276.       }
  277.       else
  278. stmt->result->row_count--;
  279.     }
  280.     (*prev)=0;
  281.      mysql_data_seek(stmt->result,0);   /* Restore pointer */
  282.   }
  283.   mysql_link_fields(stmt,SQLSTAT_fields,SQLSTAT_FIELDS);
  284.   DBUG_RETURN(SQL_SUCCESS);
  285. }
  286. //  Have DBMS set up result set of TablePrivileges.
  287. RETCODE SQL_API SQLTablePrivileges(HSTMT hstmt,
  288.    UCHAR FAR *szTableQualifier,
  289.    SWORD cbTableQualifier,
  290.    UCHAR FAR *szTableOwner,SWORD cbTableOwner,
  291.    UCHAR FAR *szTableName,SWORD cbTableName)
  292. {
  293.   DBUG_ENTER("SQLTablePrivileges");
  294.   DBUG_RETURN(set_error(((STMT FAR*) hstmt)->dbc,"08002",
  295. "MyODBC doesn't support this yet",4000));
  296. }
  297. //  Have DBMS set up result set of ColumnPrivileges.
  298. RETCODE SQL_API SQLColumnPrivileges(HSTMT hstmt,
  299.     UCHAR FAR *szTableQualifier,
  300.     SWORD cbTableQualifier,
  301.     UCHAR FAR *szTableOwner,SWORD cbTableOwner,
  302.     UCHAR FAR *szTableName,SWORD cbTableName,
  303.     UCHAR FAR *szColumnName,SWORD cbColumnName)
  304. {
  305.   DBUG_ENTER("SQLColumnPrivileges");
  306.   DBUG_RETURN(set_error(((STMT FAR*) hstmt)->dbc,"IM001",
  307. "MyODBC doesn't support this yet",4000));
  308. }
  309. //  Have DBMS set up result set of SpecialColumns.
  310. MYSQL_FIELD SQLSPECIALCOLUMNS_fields[] = {
  311.   {"Scope","MySQL SpecialColumns",NULL,FIELD_TYPE_SHORT,5,5,
  312.    NOT_NULL_FLAG},
  313.   {"Column_name","MySQL SpecialColumns",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,
  314.    NAME_LEN,NOT_NULL_FLAG},
  315.   {"Data_type","MySQL SpecialColumns",NULL,FIELD_TYPE_SHORT,5,5,
  316.    NOT_NULL_FLAG},
  317.   {"Type_name","MySQL SpecialColumns",NULL,FIELD_TYPE_VAR_STRING,20,20,
  318.    NOT_NULL_FLAG},
  319.   {"Precision","MySQL SpecialColumns",NULL,FIELD_TYPE_LONG,7,7},
  320.   {"Length","MySQL SpecialColumns",NULL,FIELD_TYPE_LONG,7,7},
  321.   {"Scale","MySQL SpecialColumns",NULL,FIELD_TYPE_SHORT,3,3},
  322.   {"Pseudo_column","MySQL SpecialColumns",NULL,FIELD_TYPE_SHORT,3,3}
  323. };
  324. const uint SQLSPECIALCOLUMNS_FIELDS=array_elements(SQLSPECIALCOLUMNS_fields);
  325. RETCODE SQL_API SQLSpecialColumns(HSTMT hstmt,UWORD fColType,
  326.   UCHAR FAR *szTableQualifier,
  327.   SWORD cbTableQualifier,
  328.   UCHAR FAR *szTableOwner,SWORD cbTableOwner,
  329.   UCHAR FAR *szTableName,SWORD cbTableName,
  330.   UWORD     fScope,UWORD fNullable)
  331. {
  332.   char buff[80],table_name[NAME_LEN+1];
  333.   uint field_count;
  334.   ulong transfer_length,precision,display_size;
  335.   STMT FAR *stmt=(STMT FAR*) hstmt;
  336.   char **row;
  337.   MEM_ROOT *alloc;
  338.   bool primary_key;
  339.   MYSQL_FIELD *field;
  340.   DBUG_ENTER("SQLSpecialColumns");
  341.   if (check_parameters(hstmt,szTableQualifier,cbTableQualifier,szTableOwner,
  342.        cbTableOwner,szTableName,&cbTableName,table_name,1))
  343.     DBUG_RETURN(SQL_ERROR);
  344.   if (!(stmt->result=mysql_list_fields(&stmt->dbc->mysql,table_name,0)))
  345.   {
  346.     strmov(stmt->dbc->sqlstate,"S1000");
  347.     return(SQL_ERROR);
  348.   }
  349.   if (fColType == SQL_ROWVER)
  350.   { /* Find possible timestamp */
  351.     stmt->result_array=
  352.       (char**) my_malloc(sizeof(char*)*SQLSPECIALCOLUMNS_FIELDS*
  353.  stmt->result->field_count, MYF(MY_FAE | MY_ZEROFILL));
  354.     /* convert mysql fields to data that odbc wants */
  355.     alloc=&stmt->result->field_alloc;
  356.     field_count=0;
  357.     mysql_field_seek(stmt->result,0);
  358.     for (row= stmt->result_array ;
  359.          (field = mysql_fetch_field(stmt->result)) ;
  360.          )
  361.     {
  362.       int type;
  363.       if ((field->type != FIELD_TYPE_TIMESTAMP))
  364.         continue;
  365.       field_count++;
  366.       sprintf(buff,"%d",SQL_SCOPE_SESSION);
  367.       row[0]=strdup_root(alloc,buff);
  368.       row[1]= field->name;
  369.       type=unireg_to_sql_datatype(stmt,field,buff,&transfer_length,&precision,&display_size);
  370.       row[3]=strdup_root(alloc,buff);
  371.       sprintf(buff,"%d",type);
  372.       row[2]=strdup_root(alloc,buff);
  373.       sprintf(buff,"%d",precision);
  374.       row[4]=strdup_root(alloc,buff);
  375.       sprintf(buff,"%d",transfer_length);
  376.       row[5]=strdup_root(alloc,buff);
  377.       sprintf(buff,"%d",field->decimals);
  378.       row[6]=strdup_root(alloc,buff);
  379.       sprintf(buff,"%d",SQL_PC_NOT_PSEUDO);
  380.       row[7]=strdup_root(alloc,buff);
  381.       row+=SQLSPECIALCOLUMNS_FIELDS;
  382.     }
  383.     stmt->result->row_count=field_count;
  384.     mysql_link_fields(stmt,SQLSPECIALCOLUMNS_fields,
  385.       SQLSPECIALCOLUMNS_FIELDS);
  386.     DBUG_RETURN(SQL_SUCCESS);
  387.   }
  388.   /*
  389.    * The optimal set of columns for identifing a row is either
  390.    * the primary key, or if there is no primary key, then
  391.    * all the fields.
  392.    */
  393.   /* Check if there is a primary (unique) key */
  394.   primary_key=0;
  395.   while ((field = mysql_fetch_field(stmt->result)))
  396.   {
  397.     if (field->flags & PRI_KEY_FLAG)
  398.     {
  399.       primary_key=1;
  400.       break;
  401.     }
  402.   }
  403.   stmt->result_array=
  404.     (char**) my_malloc(sizeof(char*)*SQLSPECIALCOLUMNS_FIELDS*
  405.        stmt->result->field_count, MYF(MY_FAE | MY_ZEROFILL));
  406.   /* convert mysql fields to data that odbc wants */
  407.   alloc=&stmt->result->field_alloc;
  408.   field_count=0;
  409.   mysql_field_seek(stmt->result,0);
  410.   for (row= stmt->result_array ;
  411.        (field = mysql_fetch_field(stmt->result)) ;
  412.        )
  413.   {
  414.     int type;
  415.     if (primary_key && !(field->flags & PRI_KEY_FLAG))
  416.       continue;
  417.     field_count++;
  418.     sprintf(buff,"%d",SQL_SCOPE_SESSION);
  419.     row[0]=strdup_root(alloc,buff);
  420.     row[1]= field->name;
  421.     type=unireg_to_sql_datatype(stmt,field,buff,&transfer_length,&precision,&display_size);
  422.     row[3]=strdup_root(alloc,buff);
  423.     sprintf(buff,"%d",type);
  424.     row[2]=strdup_root(alloc,buff);
  425.     sprintf(buff,"%d",precision);
  426.     row[4]=strdup_root(alloc,buff);
  427.     sprintf(buff,"%d",transfer_length);
  428.     row[5]=strdup_root(alloc,buff);
  429.     sprintf(buff,"%d",field->decimals);
  430.     row[6]=strdup_root(alloc,buff);
  431.     sprintf(buff,"%d",SQL_PC_NOT_PSEUDO);
  432.     row[7]=strdup_root(alloc,buff);
  433.     row+=SQLSPECIALCOLUMNS_FIELDS;
  434.   }
  435.   stmt->result->row_count=field_count;
  436.   mysql_link_fields(stmt,SQLSPECIALCOLUMNS_fields,
  437.     SQLSPECIALCOLUMNS_FIELDS);
  438.   DBUG_RETURN(SQL_SUCCESS);
  439. }
  440. //  Have DBMS set up result set of PrimaryKeys.
  441. MYSQL_FIELD SQLPRIM_KEYS_fields[] = {
  442.   {"Table_qualifer","MySQL Primary keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  443.   {"Table_owner","MySQL Primary keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  444.   {"Table_name","MySQL Primary keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,
  445.    NOT_NULL_FLAG},
  446.   {"Column_name","MySQL Primary keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,NAME_LEN,
  447.    NOT_NULL_FLAG},
  448.   {"Key_seq","MySQL Primary keys",NULL,FIELD_TYPE_SHORT,2,2,NOT_NULL_FLAG},
  449.   {"Pk_name","MySQL Primary keys",NULL,FIELD_TYPE_VAR_STRING,128,0},
  450. };
  451. const uint SQLPRIM_KEYS_FIELDS=array_elements(SQLPRIM_KEYS_fields);
  452. RETCODE SQL_API SQLPrimaryKeys(HSTMT hstmt,
  453.        UCHAR FAR *szTableQualifier,
  454.        SWORD cbTableQualifier,
  455.        UCHAR FAR *szTableOwner,SWORD cbTableOwner,
  456.        UCHAR FAR *szTableName,SWORD cbTableName)
  457. {
  458.   char buff[100],table_name[NAME_LEN+1],**data;
  459.   STMT FAR *stmt=(STMT FAR*) hstmt;
  460.   uint row_count;
  461.   MYSQL_ROW row;
  462.   DBUG_ENTER("SQLPrimaryKeys");
  463.   if (check_parameters(hstmt,szTableQualifier,cbTableQualifier,szTableOwner,
  464.        cbTableOwner,szTableName,&cbTableName,table_name,1))
  465.     DBUG_RETURN(SQL_ERROR);
  466.   remove_escape(table_name);
  467.   strxmov(buff,"show keys from ",table_name,NullS);
  468.   if (mysql_query(&stmt->dbc->mysql,buff) ||
  469.       !(stmt->result=mysql_store_result(&stmt->dbc->mysql)))
  470.   {
  471.     strmov(stmt->dbc->sqlstate,"S1000");
  472.     DBUG_RETURN(SQL_ERROR);
  473.   }
  474.   stmt->result_array= (char**) my_malloc(sizeof(char*)*SQLPRIM_KEYS_FIELDS*
  475.  stmt->result->row_count,
  476.  MYF(MY_FAE | MY_ZEROFILL));
  477.   row_count=0;
  478.   data=stmt->result_array;
  479.   while ((row = mysql_fetch_row(stmt->result)))
  480.   {
  481.     if (row[1][0] == '0') /* If unique index */
  482.     {
  483.       if (row_count && !strcmp(row[3],"1"))
  484. break; /* Allready found unique key */
  485.       row_count++;
  486.       data[0]=data[1]=0;
  487.       data[2]=row[0];
  488.       data[3]=row[4];
  489.       data[4]=row[3];
  490.       data[5]="PRIMARY";
  491.       data+=SQLPRIM_KEYS_FIELDS;
  492.     }
  493.   }
  494.   stmt->result->row_count=row_count;
  495.   mysql_link_fields(stmt,SQLPRIM_KEYS_fields,SQLPRIM_KEYS_FIELDS);
  496.   DBUG_RETURN(SQL_SUCCESS);
  497. }
  498. /*
  499. ** Have DBMS set up result set of ForeignKeys.
  500. ** mysql dosen't have foreing key, return empty set
  501. */
  502. MYSQL_FIELD SQLFORE_KEYS_fields[] = {
  503.   {"Pktable_qualifer","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  504.   {"PkTable_owner","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  505.   {"PkTable_name","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,
  506.    NAME_LEN,NOT_NULL_FLAG},
  507.   {"PkColumn_name","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,
  508.    NAME_LEN,NOT_NULL_FLAG},
  509.   {"fktable_qualifier","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0,
  510.    NOT_NULL_FLAG},
  511.   {"fkTable_owner","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,0},
  512.   {"fkTable_name","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,
  513.    NAME_LEN,NOT_NULL_FLAG},
  514.   {"fkColumn_name","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,NAME_LEN,
  515.    NAME_LEN,NOT_NULL_FLAG},
  516.   {"Key_seq","MySQL Foreign keys",NULL,FIELD_TYPE_SHORT,2,2,NOT_NULL_FLAG},
  517.   {"Update_rule","MySQL Foreign keys",NULL,FIELD_TYPE_SHORT,2,2},
  518.   {"Delete_rule","MySQL Foreign keys",NULL,FIELD_TYPE_SHORT,2,2},
  519.   {"Fk_name","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,128,0},
  520.   {"Pk_name","MySQL Foreign keys",NULL,FIELD_TYPE_VAR_STRING,128,0},
  521. };
  522. const uint SQLFORE_KEYS_FIELDS=array_elements(SQLFORE_KEYS_fields);
  523. RETCODE SQL_API SQLForeignKeys(HSTMT hstmt,
  524.        UCHAR FAR *szPkTableQualifier,
  525.        SWORD cbPkTableQualifier,
  526.        UCHAR FAR *szPkTableOwner,SWORD cbPkTableOwner,
  527.        UCHAR FAR *szPkTableName,SWORD cbPkTableName,
  528.        UCHAR FAR *szFkTableQualifier,
  529.        SWORD cbFkTableQualifier,
  530.        UCHAR FAR *szFkTableOwner,SWORD cbFkTableOwner,
  531.        UCHAR FAR *szFkTableName,SWORD cbFkTableName)
  532. {
  533.   STMT FAR *stmt=(STMT FAR*) hstmt;
  534.   DBUG_ENTER("SQLForeignKeys");
  535.   SQLFreeStmt(hstmt,MYSQL_RESET);
  536.   stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
  537.   stmt->result->eof=1;
  538.   mysql_link_fields(stmt,SQLFORE_KEYS_fields,SQLFORE_KEYS_FIELDS);
  539.   DBUG_RETURN(SQL_SUCCESS);
  540. }
  541. //  Have DBMS set up result set of Procedures.
  542. RETCODE SQL_API SQLProcedures(HSTMT hstmt,
  543.       UCHAR FAR *szProcQualifier,SWORD cbProcQualifier,
  544.       UCHAR FAR *szProcOwner,SWORD cbProcOwner,
  545.       UCHAR FAR *szProcName,SWORD cbProcName)
  546. {
  547.   return set_error(((STMT FAR*)hstmt)->dbc,"08002",
  548.    "MyODBC doesn't support this yet",4000);
  549. }
  550. //  Have DBMS set up result set of ProcedureColumns.
  551. RETCODE SQL_API SQLProcedureColumns(HSTMT hstmt,
  552.     UCHAR FAR *szProcQualifier,
  553.     SWORD cbProcQualifier,
  554.     UCHAR FAR *szProcOwner,SWORD cbProcOwner,
  555.     UCHAR FAR *szProcName,SWORD cbProcName,
  556.     UCHAR FAR *szColumnName,SWORD cbColumnName)
  557. {
  558.   return set_error(((STMT FAR*)hstmt)->dbc,"08002",
  559.    "MyODBC doesn't support this yet",4000);
  560. }
  561. static int check_parameters(HSTMT hstmt,UCHAR FAR *szTableQualifier,
  562.     SWORD cbTableQualifier,UCHAR FAR *szTableOwner,
  563.     SWORD cbTableOwner, UCHAR FAR *szTableName,
  564.     SWORD *cbTableName,
  565.     char *table_name,bool no_wildcards)
  566. {
  567. #ifdef NOT_NEEDED
  568.   {
  569.     char buff[128],*res;
  570.     if ((szTableQualifier &&
  571.          strcmp(res=fix_str(buff,szTableQualifier,cbTableQualifier),"%") &&
  572.          res[0]) ||
  573.         (szTableOwner && strcmp(res=fix_str(buff,szTableOwner,cbTableOwner),"%") &&
  574.          res[0]))
  575.     {
  576.       DBUG_PRINT("error",("szTableQualifier: '%s'  szTableOwner: '%s'  res: '%s'",
  577.    szTableQualifier,szTableOwner,res));
  578.       return set_error(((STMT FAR*) hstmt)->dbc,
  579.           "S1C00","Can't use tablequalifer or owners",0);
  580.     }
  581.   }
  582. #endif
  583.   /* Check table name and copy it to table_name */
  584.   if (!szTableName)
  585.   {
  586.     szTableName="";
  587.     *cbTableName=0;
  588.   }
  589.   if (*cbTableName == SQL_NTS)
  590.     *cbTableName=strlen(szTableName);
  591.   if ((uint) *cbTableName > NAME_LEN)
  592.     return set_error(((STMT FAR*) hstmt)->dbc,"SC1090","Invalid table name",0);
  593.   strmake(table_name,szTableName,*cbTableName);
  594.   if (no_wildcards && (!table_name[0] || strchr(table_name,'%')))
  595.     return(set_error(((STMT FAR*) hstmt)->dbc,"S1C00",
  596.      "Can't use wildcards in table name",0));
  597.   SQLFreeStmt(hstmt,MYSQL_RESET);
  598.   return 0;
  599. }