DatabaseMetaData.java
上传用户:sxlinghang
上传日期:2022-07-20
资源大小:1405k
文件大小:231k
源码类别:

数据库编程

开发平台:

Java

  1.     }
  2.     /**
  3.      * Get a comma separated list of time and date functions.
  4.      *
  5.      * @return the list
  6.      *
  7.      * @throws java.sql.SQLException DOCUMENT ME!
  8.      */
  9.     public String getTimeDateFunctions() throws java.sql.SQLException {
  10.         return "DAYOFWEEK,WEEKDAY,DAYOFMONTH,DAYOFYEAR,MONTH,DAYNAME,"
  11.         + "MONTHNAME,QUARTER,WEEK,YEAR,HOUR,MINUTE,SECOND,PERIOD_ADD,"
  12.         + "PERIOD_DIFF,TO_DAYS,FROM_DAYS,DATE_FORMAT,TIME_FORMAT,"
  13.         + "CURDATE,CURRENT_DATE,CURTIME,CURRENT_TIME,NOW,SYSDATE,"
  14.         + "CURRENT_TIMESTAMP,UNIX_TIMESTAMP,FROM_UNIXTIME,"
  15.         + "SEC_TO_TIME,TIME_TO_SEC";
  16.     }
  17.     /**
  18.      * Get a description of all the standard SQL types supported by this
  19.      * database. They are ordered by DATA_TYPE and then by how closely the
  20.      * data type maps to the corresponding JDBC SQL type.
  21.      * 
  22.      * <P>
  23.      * Each type description has the following columns:
  24.      * 
  25.      * <OL>
  26.      * <li>
  27.      * <B>TYPE_NAME</B> String => Type name
  28.      * </li>
  29.      * <li>
  30.      * <B>DATA_TYPE</B> short => SQL data type from java.sql.Types
  31.      * </li>
  32.      * <li>
  33.      * <B>PRECISION</B> int => maximum precision
  34.      * </li>
  35.      * <li>
  36.      * <B>LITERAL_PREFIX</B> String => prefix used to quote a literal (may be
  37.      * null)
  38.      * </li>
  39.      * <li>
  40.      * <B>LITERAL_SUFFIX</B> String => suffix used to quote a literal (may be
  41.      * null)
  42.      * </li>
  43.      * <li>
  44.      * <B>CREATE_PARAMS</B> String => parameters used in creating the type (may
  45.      * be null)
  46.      * </li>
  47.      * <li>
  48.      * <B>NULLABLE</B> short => can you use NULL for this type?
  49.      * 
  50.      * <UL>
  51.      * <li>
  52.      * typeNoNulls - does not allow NULL values
  53.      * </li>
  54.      * <li>
  55.      * typeNullable - allows NULL values
  56.      * </li>
  57.      * <li>
  58.      * typeNullableUnknown - nullability unknown
  59.      * </li>
  60.      * </ul>
  61.      * 
  62.      * </li>
  63.      * <li>
  64.      * <B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
  65.      * </li>
  66.      * <li>
  67.      * <B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
  68.      * 
  69.      * <UL>
  70.      * <li>
  71.      * typePredNone - No support
  72.      * </li>
  73.      * <li>
  74.      * typePredChar - Only supported with WHERE .. LIKE
  75.      * </li>
  76.      * <li>
  77.      * typePredBasic - Supported except for WHERE .. LIKE
  78.      * </li>
  79.      * <li>
  80.      * typeSearchable - Supported for all WHERE ..
  81.      * </li>
  82.      * </ul>
  83.      * 
  84.      * </li>
  85.      * <li>
  86.      * <B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
  87.      * </li>
  88.      * <li>
  89.      * <B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
  90.      * </li>
  91.      * <li>
  92.      * <B>AUTO_INCREMENT</B> boolean => can it be used for an auto-increment
  93.      * value?
  94.      * </li>
  95.      * <li>
  96.      * <B>LOCAL_TYPE_NAME</B> String => localized version of type name (may be
  97.      * null)
  98.      * </li>
  99.      * <li>
  100.      * <B>MINIMUM_SCALE</B> short => minimum scale supported
  101.      * </li>
  102.      * <li>
  103.      * <B>MAXIMUM_SCALE</B> short => maximum scale supported
  104.      * </li>
  105.      * <li>
  106.      * <B>SQL_DATA_TYPE</B> int => unused
  107.      * </li>
  108.      * <li>
  109.      * <B>SQL_DATETIME_SUB</B> int => unused
  110.      * </li>
  111.      * <li>
  112.      * <B>NUM_PREC_RADIX</B> int => usually 2 or 10
  113.      * </li>
  114.      * </ol>
  115.      * </p>
  116.      *
  117.      * @return ResultSet each row is a SQL type description
  118.      *
  119.      * @throws java.sql.SQLException DOCUMENT ME!
  120.      */
  121.     /**
  122.      * Get a description of all the standard SQL types supported by this
  123.      * database. They are ordered by DATA_TYPE and then by how closely the
  124.      * data type maps to the corresponding JDBC SQL type.
  125.      * 
  126.      * <P>
  127.      * Each type description has the following columns:
  128.      * 
  129.      * <OL>
  130.      * <li>
  131.      * <B>TYPE_NAME</B> String => Type name
  132.      * </li>
  133.      * <li>
  134.      * <B>DATA_TYPE</B> short => SQL data type from java.sql.Types
  135.      * </li>
  136.      * <li>
  137.      * <B>PRECISION</B> int => maximum precision
  138.      * </li>
  139.      * <li>
  140.      * <B>LITERAL_PREFIX</B> String => prefix used to quote a literal (may be
  141.      * null)
  142.      * </li>
  143.      * <li>
  144.      * <B>LITERAL_SUFFIX</B> String => suffix used to quote a literal (may be
  145.      * null)
  146.      * </li>
  147.      * <li>
  148.      * <B>CREATE_PARAMS</B> String => parameters used in creating the type (may
  149.      * be null)
  150.      * </li>
  151.      * <li>
  152.      * <B>NULLABLE</B> short => can you use NULL for this type?
  153.      * 
  154.      * <UL>
  155.      * <li>
  156.      * typeNoNulls - does not allow NULL values
  157.      * </li>
  158.      * <li>
  159.      * typeNullable - allows NULL values
  160.      * </li>
  161.      * <li>
  162.      * typeNullableUnknown - nullability unknown
  163.      * </li>
  164.      * </ul>
  165.      * 
  166.      * </li>
  167.      * <li>
  168.      * <B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
  169.      * </li>
  170.      * <li>
  171.      * <B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
  172.      * 
  173.      * <UL>
  174.      * <li>
  175.      * typePredNone - No support
  176.      * </li>
  177.      * <li>
  178.      * typePredChar - Only supported with WHERE .. LIKE
  179.      * </li>
  180.      * <li>
  181.      * typePredBasic - Supported except for WHERE .. LIKE
  182.      * </li>
  183.      * <li>
  184.      * typeSearchable - Supported for all WHERE ..
  185.      * </li>
  186.      * </ul>
  187.      * 
  188.      * </li>
  189.      * <li>
  190.      * <B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
  191.      * </li>
  192.      * <li>
  193.      * <B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
  194.      * </li>
  195.      * <li>
  196.      * <B>AUTO_INCREMENT</B> boolean => can it be used for an auto-increment
  197.      * value?
  198.      * </li>
  199.      * <li>
  200.      * <B>LOCAL_TYPE_NAME</B> String => localized version of type name (may be
  201.      * null)
  202.      * </li>
  203.      * <li>
  204.      * <B>MINIMUM_SCALE</B> short => minimum scale supported
  205.      * </li>
  206.      * <li>
  207.      * <B>MAXIMUM_SCALE</B> short => maximum scale supported
  208.      * </li>
  209.      * <li>
  210.      * <B>SQL_DATA_TYPE</B> int => unused
  211.      * </li>
  212.      * <li>
  213.      * <B>SQL_DATETIME_SUB</B> int => unused
  214.      * </li>
  215.      * <li>
  216.      * <B>NUM_PREC_RADIX</B> int => usually 2 or 10
  217.      * </li>
  218.      * </ol>
  219.      * </p>
  220.      *
  221.      * @return ResultSet each row is a SQL type description
  222.      *
  223.      * @throws java.sql.SQLException DOCUMENT ME!
  224.      */
  225.     public java.sql.ResultSet getTypeInfo() throws java.sql.SQLException {
  226.         Field[] fields = new Field[18];
  227.         fields[0] = new Field("", "TYPE_NAME", Types.CHAR, 32);
  228.         fields[1] = new Field("", "DATA_TYPE", Types.SMALLINT, 5);
  229.         fields[2] = new Field("", "PRECISION", Types.INTEGER, 10);
  230.         fields[3] = new Field("", "LITERAL_PREFIX", Types.CHAR, 4);
  231.         fields[4] = new Field("", "LITERAL_SUFFIX", Types.CHAR, 4);
  232.         fields[5] = new Field("", "CREATE_PARAMS", Types.CHAR, 32);
  233.         fields[6] = new Field("", "NULLABLE", Types.SMALLINT, 5);
  234.         fields[7] = new Field("", "CASE_SENSITIVE", Types.CHAR, 3);
  235.         fields[8] = new Field("", "SEARCHABLE", Types.SMALLINT, 3);
  236.         fields[9] = new Field("", "UNSIGNED_ATTRIBUTE", Types.CHAR, 3);
  237.         fields[10] = new Field("", "FIXED_PREC_SCALE", Types.CHAR, 3);
  238.         fields[11] = new Field("", "AUTO_INCREMENT", Types.CHAR, 3);
  239.         fields[12] = new Field("", "LOCAL_TYPE_NAME", Types.CHAR, 32);
  240.         fields[13] = new Field("", "MINIMUM_SCALE", Types.SMALLINT, 5);
  241.         fields[14] = new Field("", "MAXIMUM_SCALE", Types.SMALLINT, 5);
  242.         fields[15] = new Field("", "SQL_DATA_TYPE", Types.INTEGER, 10);
  243.         fields[16] = new Field("", "SQL_DATETIME_SUB", Types.INTEGER, 10);
  244.         fields[17] = new Field("", "NUM_PREC_RADIX", Types.INTEGER, 10);
  245.         byte[][] rowVal = null;
  246.         ArrayList tuples = new ArrayList();
  247.         /*
  248.          * The following are ordered by java.sql.Types, and
  249.          * then by how closely the MySQL type matches the
  250.          * JDBC Type (per spec)
  251.          */
  252.         /*
  253.          * MySQL Type: BIT (silently converted to TINYINT(1))
  254.          * JDBC  Type: BIT
  255.          */
  256.         rowVal = new byte[18][];
  257.         rowVal[0] = s2b("BIT");
  258.         rowVal[1] = Integer.toString(java.sql.Types.BIT).getBytes();
  259.         // JDBC Data type
  260.         rowVal[2] = s2b("1"); // Precision
  261.         rowVal[3] = s2b(""); // Literal Prefix
  262.         rowVal[4] = s2b(""); // Literal Suffix
  263.         rowVal[5] = s2b(""); // Create Params
  264.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  265.                            .getBytes();
  266.         // Nullable
  267.         rowVal[7] = s2b("true"); // Case Sensitive
  268.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  269.                            .getBytes();
  270.         // Searchable
  271.         rowVal[9] = s2b("false"); // Unsignable
  272.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  273.         rowVal[11] = s2b("false"); // Auto Increment
  274.         rowVal[12] = s2b("BIT"); // Locale Type Name
  275.         rowVal[13] = s2b("0"); // Minimum Scale
  276.         rowVal[14] = s2b("0"); // Maximum Scale
  277.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  278.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  279.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  280.         tuples.add(rowVal);
  281.         /*
  282.          * MySQL Type: BOOL (silently converted to TINYINT(1))
  283.          * JDBC  Type: BIT
  284.          */
  285.         rowVal = new byte[18][];
  286.         rowVal[0] = s2b("BOOL");
  287.         rowVal[1] = Integer.toString(java.sql.Types.BIT).getBytes();
  288.         // JDBC Data type
  289.         rowVal[2] = s2b("1"); // Precision
  290.         rowVal[3] = s2b(""); // Literal Prefix
  291.         rowVal[4] = s2b(""); // Literal Suffix
  292.         rowVal[5] = s2b(""); // Create Params
  293.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  294.                            .getBytes();
  295.         // Nullable
  296.         rowVal[7] = s2b("true"); // Case Sensitive
  297.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  298.                            .getBytes();
  299.         // Searchable
  300.         rowVal[9] = s2b("false"); // Unsignable
  301.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  302.         rowVal[11] = s2b("false"); // Auto Increment
  303.         rowVal[12] = s2b("BOOL"); // Locale Type Name
  304.         rowVal[13] = s2b("0"); // Minimum Scale
  305.         rowVal[14] = s2b("0"); // Maximum Scale
  306.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  307.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  308.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  309.         tuples.add(rowVal);
  310.         /*
  311.          * MySQL Type: TINYINT
  312.          * JDBC  Type: TINYINT
  313.          */
  314.         rowVal = new byte[18][];
  315.         rowVal[0] = s2b("TINYINT");
  316.         rowVal[1] = Integer.toString(java.sql.Types.TINYINT).getBytes();
  317.         // JDBC Data type
  318.         rowVal[2] = s2b("3"); // Precision
  319.         rowVal[3] = s2b(""); // Literal Prefix
  320.         rowVal[4] = s2b(""); // Literal Suffix
  321.         rowVal[5] = s2b("[(M)] [UNSIGNED] [ZEROFILL]"); // Create Params
  322.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  323.                            .getBytes();
  324.         // Nullable
  325.         rowVal[7] = s2b("false"); // Case Sensitive
  326.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  327.                            .getBytes();
  328.         // Searchable
  329.         rowVal[9] = s2b("true"); // Unsignable
  330.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  331.         rowVal[11] = s2b("true"); // Auto Increment
  332.         rowVal[12] = s2b("TINYINT"); // Locale Type Name
  333.         rowVal[13] = s2b("0"); // Minimum Scale
  334.         rowVal[14] = s2b("0"); // Maximum Scale
  335.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  336.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  337.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  338.         tuples.add(rowVal);
  339.         /*
  340.          * MySQL Type: BIGINT
  341.          * JDBC  Type: BIGINT
  342.          */
  343.         rowVal = new byte[18][];
  344.         rowVal[0] = s2b("BIGINT");
  345.         rowVal[1] = Integer.toString(java.sql.Types.BIGINT).getBytes();
  346.         // JDBC Data type
  347.         rowVal[2] = s2b("19"); // Precision
  348.         rowVal[3] = s2b(""); // Literal Prefix
  349.         rowVal[4] = s2b(""); // Literal Suffix
  350.         rowVal[5] = s2b("[(M)] [UNSIGNED] [ZEROFILL]"); // Create Params
  351.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  352.                            .getBytes();
  353.         // Nullable
  354.         rowVal[7] = s2b("false"); // Case Sensitive
  355.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  356.                            .getBytes();
  357.         // Searchable
  358.         rowVal[9] = s2b("true"); // Unsignable
  359.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  360.         rowVal[11] = s2b("true"); // Auto Increment
  361.         rowVal[12] = s2b("BIGINT"); // Locale Type Name
  362.         rowVal[13] = s2b("0"); // Minimum Scale
  363.         rowVal[14] = s2b("0"); // Maximum Scale
  364.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  365.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  366.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  367.         tuples.add(rowVal);
  368.         /*
  369.          * MySQL Type: LONG VARBINARY
  370.          * JDBC  Type: LONGVARBINARY
  371.          */
  372.         rowVal = new byte[18][];
  373.         rowVal[0] = s2b("LONG VARBINARY");
  374.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARBINARY).getBytes();
  375.         // JDBC Data type
  376.         rowVal[2] = s2b("16777215"); // Precision
  377.         rowVal[3] = s2b("'"); // Literal Prefix
  378.         rowVal[4] = s2b("'"); // Literal Suffix
  379.         rowVal[5] = s2b(""); // Create Params
  380.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  381.                            .getBytes();
  382.         // Nullable
  383.         rowVal[7] = s2b("true"); // Case Sensitive
  384.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  385.                            .getBytes();
  386.         // Searchable
  387.         rowVal[9] = s2b("false"); // Unsignable
  388.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  389.         rowVal[11] = s2b("false"); // Auto Increment
  390.         rowVal[12] = s2b("LONG VARBINARY"); // Locale Type Name
  391.         rowVal[13] = s2b("0"); // Minimum Scale
  392.         rowVal[14] = s2b("0"); // Maximum Scale
  393.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  394.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  395.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  396.         tuples.add(rowVal);
  397.         /*
  398.          * MySQL Type: MEDIUMBLOB
  399.          * JDBC  Type: LONGVARBINARY
  400.          */
  401.         rowVal = new byte[18][];
  402.         rowVal[0] = s2b("MEDIUMBLOB");
  403.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARBINARY).getBytes();
  404.         // JDBC Data type
  405.         rowVal[2] = s2b("16777215"); // Precision
  406.         rowVal[3] = s2b("'"); // Literal Prefix
  407.         rowVal[4] = s2b("'"); // Literal Suffix
  408.         rowVal[5] = s2b(""); // Create Params
  409.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  410.                            .getBytes();
  411.         // Nullable
  412.         rowVal[7] = s2b("true"); // Case Sensitive
  413.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  414.                            .getBytes();
  415.         // Searchable
  416.         rowVal[9] = s2b("false"); // Unsignable
  417.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  418.         rowVal[11] = s2b("false"); // Auto Increment
  419.         rowVal[12] = s2b("MEDIUMBLOB"); // Locale Type Name
  420.         rowVal[13] = s2b("0"); // Minimum Scale
  421.         rowVal[14] = s2b("0"); // Maximum Scale
  422.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  423.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  424.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  425.         tuples.add(rowVal);
  426.         /*
  427.          * MySQL Type: LONGBLOB
  428.          * JDBC  Type: LONGVARBINARY
  429.          */
  430.         rowVal = new byte[18][];
  431.         rowVal[0] = s2b("LONGBLOB");
  432.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARBINARY).getBytes();
  433.         // JDBC Data type
  434.         rowVal[2] = Integer.toString(Integer.MAX_VALUE).getBytes();
  435.         // Precision
  436.         rowVal[3] = s2b("'"); // Literal Prefix
  437.         rowVal[4] = s2b("'"); // Literal Suffix
  438.         rowVal[5] = s2b(""); // Create Params
  439.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  440.                            .getBytes();
  441.         // Nullable
  442.         rowVal[7] = s2b("true"); // Case Sensitive
  443.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  444.                            .getBytes();
  445.         // Searchable
  446.         rowVal[9] = s2b("false"); // Unsignable
  447.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  448.         rowVal[11] = s2b("false"); // Auto Increment
  449.         rowVal[12] = s2b("LONGBLOB"); // Locale Type Name
  450.         rowVal[13] = s2b("0"); // Minimum Scale
  451.         rowVal[14] = s2b("0"); // Maximum Scale
  452.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  453.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  454.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  455.         tuples.add(rowVal);
  456.         /*
  457.          * MySQL Type: BLOB
  458.          * JDBC  Type: LONGVARBINARY
  459.          */
  460.         rowVal = new byte[18][];
  461.         rowVal[0] = s2b("BLOB");
  462.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARBINARY).getBytes();
  463.         // JDBC Data type
  464.         rowVal[2] = s2b("65535"); // Precision
  465.         rowVal[3] = s2b("'"); // Literal Prefix
  466.         rowVal[4] = s2b("'"); // Literal Suffix
  467.         rowVal[5] = s2b(""); // Create Params
  468.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  469.                            .getBytes();
  470.         // Nullable
  471.         rowVal[7] = s2b("true"); // Case Sensitive
  472.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  473.                            .getBytes();
  474.         // Searchable
  475.         rowVal[9] = s2b("false"); // Unsignable
  476.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  477.         rowVal[11] = s2b("false"); // Auto Increment
  478.         rowVal[12] = s2b("BLOB"); // Locale Type Name
  479.         rowVal[13] = s2b("0"); // Minimum Scale
  480.         rowVal[14] = s2b("0"); // Maximum Scale
  481.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  482.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  483.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  484.         tuples.add(rowVal);
  485.         /*
  486.          * MySQL Type: TINYBLOB
  487.          * JDBC  Type: LONGVARBINARY
  488.          */
  489.         rowVal = new byte[18][];
  490.         rowVal[0] = s2b("TINYBLOB");
  491.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARBINARY).getBytes();
  492.         // JDBC Data type
  493.         rowVal[2] = s2b("255"); // Precision
  494.         rowVal[3] = s2b("'"); // Literal Prefix
  495.         rowVal[4] = s2b("'"); // Literal Suffix
  496.         rowVal[5] = s2b(""); // Create Params
  497.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  498.                            .getBytes();
  499.         // Nullable
  500.         rowVal[7] = s2b("true"); // Case Sensitive
  501.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  502.                            .getBytes();
  503.         // Searchable
  504.         rowVal[9] = s2b("false"); // Unsignable
  505.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  506.         rowVal[11] = s2b("false"); // Auto Increment
  507.         rowVal[12] = s2b("TINYBLOB"); // Locale Type Name
  508.         rowVal[13] = s2b("0"); // Minimum Scale
  509.         rowVal[14] = s2b("0"); // Maximum Scale
  510.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  511.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  512.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  513.         tuples.add(rowVal);
  514.         /*
  515.          * MySQL Type: VARBINARY (sliently converted to VARCHAR(M) BINARY)
  516.          * JDBC  Type: VARBINARY
  517.          */
  518.         rowVal = new byte[18][];
  519.         rowVal[0] = s2b("VARBINARY");
  520.         rowVal[1] = Integer.toString(java.sql.Types.VARBINARY).getBytes();
  521.         // JDBC Data type
  522.         rowVal[2] = s2b("255"); // Precision
  523.         rowVal[3] = s2b("'"); // Literal Prefix
  524.         rowVal[4] = s2b("'"); // Literal Suffix
  525.         rowVal[5] = s2b("(M)"); // Create Params
  526.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  527.                            .getBytes();
  528.         // Nullable
  529.         rowVal[7] = s2b("true"); // Case Sensitive
  530.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  531.                            .getBytes();
  532.         // Searchable
  533.         rowVal[9] = s2b("false"); // Unsignable
  534.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  535.         rowVal[11] = s2b("false"); // Auto Increment
  536.         rowVal[12] = s2b("VARBINARY"); // Locale Type Name
  537.         rowVal[13] = s2b("0"); // Minimum Scale
  538.         rowVal[14] = s2b("0"); // Maximum Scale
  539.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  540.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  541.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  542.         tuples.add(rowVal);
  543.         /*
  544.          * MySQL Type: BINARY (silently converted to CHAR(M) BINARY)
  545.          * JDBC  Type: BINARY
  546.          */
  547.         rowVal = new byte[18][];
  548.         rowVal[0] = s2b("BINARY");
  549.         rowVal[1] = Integer.toString(java.sql.Types.BINARY).getBytes();
  550.         // JDBC Data type
  551.         rowVal[2] = s2b("255"); // Precision
  552.         rowVal[3] = s2b("'"); // Literal Prefix
  553.         rowVal[4] = s2b("'"); // Literal Suffix
  554.         rowVal[5] = s2b("(M)"); // Create Params
  555.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  556.                            .getBytes();
  557.         // Nullable
  558.         rowVal[7] = s2b("true"); // Case Sensitive
  559.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  560.                            .getBytes();
  561.         // Searchable
  562.         rowVal[9] = s2b("false"); // Unsignable
  563.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  564.         rowVal[11] = s2b("false"); // Auto Increment
  565.         rowVal[12] = s2b("BINARY"); // Locale Type Name
  566.         rowVal[13] = s2b("0"); // Minimum Scale
  567.         rowVal[14] = s2b("0"); // Maximum Scale
  568.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  569.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  570.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  571.         tuples.add(rowVal);
  572.         /*
  573.          * MySQL Type: LONG VARCHAR
  574.          * JDBC  Type: LONGVARCHAR
  575.          */
  576.         rowVal = new byte[18][];
  577.         rowVal[0] = s2b("LONG VARCHAR");
  578.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARCHAR).getBytes();
  579.         // JDBC Data type
  580.         rowVal[2] = s2b("16777215"); // Precision
  581.         rowVal[3] = s2b("'"); // Literal Prefix
  582.         rowVal[4] = s2b("'"); // Literal Suffix
  583.         rowVal[5] = s2b(""); // Create Params
  584.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  585.                            .getBytes();
  586.         // Nullable
  587.         rowVal[7] = s2b("false"); // Case Sensitive
  588.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  589.                            .getBytes();
  590.         // Searchable
  591.         rowVal[9] = s2b("false"); // Unsignable
  592.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  593.         rowVal[11] = s2b("false"); // Auto Increment
  594.         rowVal[12] = s2b("LONG VARCHAR"); // Locale Type Name
  595.         rowVal[13] = s2b("0"); // Minimum Scale
  596.         rowVal[14] = s2b("0"); // Maximum Scale
  597.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  598.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  599.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  600.         tuples.add(rowVal);
  601.         /*
  602.          * MySQL Type: MEDIUMTEXT
  603.          * JDBC  Type: LONGVARCHAR
  604.          */
  605.         rowVal = new byte[18][];
  606.         rowVal[0] = s2b("MEDIUMTEXT");
  607.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARCHAR).getBytes();
  608.         // JDBC Data type
  609.         rowVal[2] = s2b("16777215"); // Precision
  610.         rowVal[3] = s2b("'"); // Literal Prefix
  611.         rowVal[4] = s2b("'"); // Literal Suffix
  612.         rowVal[5] = s2b(""); // Create Params
  613.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  614.                            .getBytes();
  615.         // Nullable
  616.         rowVal[7] = s2b("false"); // Case Sensitive
  617.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  618.                            .getBytes();
  619.         // Searchable
  620.         rowVal[9] = s2b("false"); // Unsignable
  621.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  622.         rowVal[11] = s2b("false"); // Auto Increment
  623.         rowVal[12] = s2b("MEDIUMTEXT"); // Locale Type Name
  624.         rowVal[13] = s2b("0"); // Minimum Scale
  625.         rowVal[14] = s2b("0"); // Maximum Scale
  626.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  627.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  628.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  629.         tuples.add(rowVal);
  630.         /*
  631.          * MySQL Type: LONGTEXT
  632.          * JDBC  Type: LONGVARCHAR
  633.          */
  634.         rowVal = new byte[18][];
  635.         rowVal[0] = s2b("LONGTEXT");
  636.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARCHAR).getBytes();
  637.         // JDBC Data type
  638.         rowVal[2] = Integer.toString(Integer.MAX_VALUE).getBytes();
  639.         // Precision
  640.         rowVal[3] = s2b("'"); // Literal Prefix
  641.         rowVal[4] = s2b("'"); // Literal Suffix
  642.         rowVal[5] = s2b(""); // Create Params
  643.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  644.                            .getBytes();
  645.         // Nullable
  646.         rowVal[7] = s2b("false"); // Case Sensitive
  647.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  648.                            .getBytes();
  649.         // Searchable
  650.         rowVal[9] = s2b("false"); // Unsignable
  651.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  652.         rowVal[11] = s2b("false"); // Auto Increment
  653.         rowVal[12] = s2b("LONGTEXT"); // Locale Type Name
  654.         rowVal[13] = s2b("0"); // Minimum Scale
  655.         rowVal[14] = s2b("0"); // Maximum Scale
  656.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  657.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  658.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  659.         tuples.add(rowVal);
  660.         /*
  661.          * MySQL Type: TEXT
  662.          * JDBC  Type: LONGVARCHAR
  663.          */
  664.         rowVal = new byte[18][];
  665.         rowVal[0] = s2b("TEXT");
  666.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARCHAR).getBytes();
  667.         // JDBC Data type
  668.         rowVal[2] = s2b("65535"); // Precision
  669.         rowVal[3] = s2b("'"); // Literal Prefix
  670.         rowVal[4] = s2b("'"); // Literal Suffix
  671.         rowVal[5] = s2b(""); // Create Params
  672.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  673.                            .getBytes();
  674.         // Nullable
  675.         rowVal[7] = s2b("false"); // Case Sensitive
  676.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  677.                            .getBytes();
  678.         // Searchable
  679.         rowVal[9] = s2b("false"); // Unsignable
  680.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  681.         rowVal[11] = s2b("false"); // Auto Increment
  682.         rowVal[12] = s2b("TEXT"); // Locale Type Name
  683.         rowVal[13] = s2b("0"); // Minimum Scale
  684.         rowVal[14] = s2b("0"); // Maximum Scale
  685.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  686.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  687.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  688.         tuples.add(rowVal);
  689.         /*
  690.          * MySQL Type: TINYTEXT
  691.          * JDBC  Type: LONGVARCHAR
  692.          */
  693.         rowVal = new byte[18][];
  694.         rowVal[0] = s2b("TINYTEXT");
  695.         rowVal[1] = Integer.toString(java.sql.Types.LONGVARCHAR).getBytes();
  696.         // JDBC Data type
  697.         rowVal[2] = s2b("255"); // Precision
  698.         rowVal[3] = s2b("'"); // Literal Prefix
  699.         rowVal[4] = s2b("'"); // Literal Suffix
  700.         rowVal[5] = s2b(""); // Create Params
  701.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  702.                            .getBytes();
  703.         // Nullable
  704.         rowVal[7] = s2b("false"); // Case Sensitive
  705.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  706.                            .getBytes();
  707.         // Searchable
  708.         rowVal[9] = s2b("false"); // Unsignable
  709.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  710.         rowVal[11] = s2b("false"); // Auto Increment
  711.         rowVal[12] = s2b("TINYTEXT"); // Locale Type Name
  712.         rowVal[13] = s2b("0"); // Minimum Scale
  713.         rowVal[14] = s2b("0"); // Maximum Scale
  714.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  715.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  716.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  717.         tuples.add(rowVal);
  718.         /*
  719.          * MySQL Type: CHAR
  720.          * JDBC  Type: CHAR
  721.          */
  722.         rowVal = new byte[18][];
  723.         rowVal[0] = s2b("CHAR");
  724.         rowVal[1] = Integer.toString(java.sql.Types.CHAR).getBytes();
  725.         // JDBC Data type
  726.         rowVal[2] = s2b("255"); // Precision
  727.         rowVal[3] = s2b("'"); // Literal Prefix
  728.         rowVal[4] = s2b("'"); // Literal Suffix
  729.         rowVal[5] = s2b("(M)"); // Create Params
  730.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  731.                            .getBytes();
  732.         // Nullable
  733.         rowVal[7] = s2b("false"); // Case Sensitive
  734.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  735.                            .getBytes();
  736.         // Searchable
  737.         rowVal[9] = s2b("false"); // Unsignable
  738.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  739.         rowVal[11] = s2b("false"); // Auto Increment
  740.         rowVal[12] = s2b("CHAR"); // Locale Type Name
  741.         rowVal[13] = s2b("0"); // Minimum Scale
  742.         rowVal[14] = s2b("0"); // Maximum Scale
  743.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  744.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  745.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  746.         tuples.add(rowVal);
  747.         /*
  748.          * MySQL Type: NUMERIC (silently converted to DECIMAL)
  749.          * JDBC  Type: NUMERIC
  750.          */
  751.         rowVal = new byte[18][];
  752.         rowVal[0] = s2b("NUMERIC");
  753.         rowVal[1] = Integer.toString(java.sql.Types.NUMERIC).getBytes();
  754.         // JDBC Data type
  755.         rowVal[2] = s2b("17"); // Precision
  756.         rowVal[3] = s2b(""); // Literal Prefix
  757.         rowVal[4] = s2b(""); // Literal Suffix
  758.         rowVal[5] = s2b("[(M[,D])] [ZEROFILL]"); // Create Params
  759.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  760.                            .getBytes();
  761.         // Nullable
  762.         rowVal[7] = s2b("false"); // Case Sensitive
  763.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  764.                            .getBytes();
  765.         // Searchable
  766.         rowVal[9] = s2b("false"); // Unsignable
  767.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  768.         rowVal[11] = s2b("true"); // Auto Increment
  769.         rowVal[12] = s2b("NUMERIC"); // Locale Type Name
  770.         rowVal[13] = s2b("308"); // Minimum Scale
  771.         rowVal[14] = s2b("308"); // Maximum Scale
  772.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  773.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  774.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  775.         tuples.add(rowVal);
  776.         /*
  777.          * MySQL Type: DECIMAL
  778.          * JDBC  Type: DECIMAL
  779.          */
  780.         rowVal = new byte[18][];
  781.         rowVal[0] = s2b("DECIMAL");
  782.         rowVal[1] = Integer.toString(java.sql.Types.DECIMAL).getBytes();
  783.         // JDBC Data type
  784.         rowVal[2] = s2b("17"); // Precision
  785.         rowVal[3] = s2b(""); // Literal Prefix
  786.         rowVal[4] = s2b(""); // Literal Suffix
  787.         rowVal[5] = s2b("[(M[,D])] [ZEROFILL]"); // Create Params
  788.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  789.                            .getBytes();
  790.         // Nullable
  791.         rowVal[7] = s2b("false"); // Case Sensitive
  792.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  793.                            .getBytes();
  794.         // Searchable
  795.         rowVal[9] = s2b("false"); // Unsignable
  796.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  797.         rowVal[11] = s2b("true"); // Auto Increment
  798.         rowVal[12] = s2b("DECIMAL"); // Locale Type Name
  799.         rowVal[13] = s2b("-308"); // Minimum Scale
  800.         rowVal[14] = s2b("308"); // Maximum Scale
  801.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  802.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  803.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  804.         tuples.add(rowVal);
  805.         /*
  806.          * MySQL Type: INTEGER
  807.          * JDBC  Type: INTEGER
  808.          */
  809.         rowVal = new byte[18][];
  810.         rowVal[0] = s2b("INTEGER");
  811.         rowVal[1] = Integer.toString(java.sql.Types.INTEGER).getBytes();
  812.         // JDBC Data type
  813.         rowVal[2] = s2b("10"); // Precision
  814.         rowVal[3] = s2b(""); // Literal Prefix
  815.         rowVal[4] = s2b(""); // Literal Suffix
  816.         rowVal[5] = s2b("[(M)] [UNSIGNED] [ZEROFILL]"); // Create Params
  817.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  818.                            .getBytes();
  819.         // Nullable
  820.         rowVal[7] = s2b("false"); // Case Sensitive
  821.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  822.                            .getBytes();
  823.         // Searchable
  824.         rowVal[9] = s2b("true"); // Unsignable
  825.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  826.         rowVal[11] = s2b("true"); // Auto Increment
  827.         rowVal[12] = s2b("INTEGER"); // Locale Type Name
  828.         rowVal[13] = s2b("0"); // Minimum Scale
  829.         rowVal[14] = s2b("0"); // Maximum Scale
  830.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  831.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  832.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  833.         tuples.add(rowVal);
  834.         /*
  835.          * MySQL Type: INT
  836.          * JDBC  Type: INTEGER
  837.          */
  838.         rowVal = new byte[18][];
  839.         rowVal[0] = s2b("INT");
  840.         rowVal[1] = Integer.toString(java.sql.Types.INTEGER).getBytes();
  841.         // JDBC Data type
  842.         rowVal[2] = s2b("10"); // Precision
  843.         rowVal[3] = s2b(""); // Literal Prefix
  844.         rowVal[4] = s2b(""); // Literal Suffix
  845.         rowVal[5] = s2b("[(M)] [UNSIGNED] [ZEROFILL]"); // Create Params
  846.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  847.                            .getBytes();
  848.         // Nullable
  849.         rowVal[7] = s2b("false"); // Case Sensitive
  850.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  851.                            .getBytes();
  852.         // Searchable
  853.         rowVal[9] = s2b("true"); // Unsignable
  854.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  855.         rowVal[11] = s2b("true"); // Auto Increment
  856.         rowVal[12] = s2b("INT"); // Locale Type Name
  857.         rowVal[13] = s2b("0"); // Minimum Scale
  858.         rowVal[14] = s2b("0"); // Maximum Scale
  859.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  860.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  861.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  862.         tuples.add(rowVal);
  863.         /*
  864.          * MySQL Type: MEDIUMINT
  865.          * JDBC  Type: INTEGER
  866.          */
  867.         rowVal = new byte[18][];
  868.         rowVal[0] = s2b("MEDIUMINT");
  869.         rowVal[1] = Integer.toString(java.sql.Types.INTEGER).getBytes();
  870.         // JDBC Data type
  871.         rowVal[2] = s2b("7"); // Precision
  872.         rowVal[3] = s2b(""); // Literal Prefix
  873.         rowVal[4] = s2b(""); // Literal Suffix
  874.         rowVal[5] = s2b("[(M)] [UNSIGNED] [ZEROFILL]"); // Create Params
  875.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  876.                            .getBytes();
  877.         // Nullable
  878.         rowVal[7] = s2b("false"); // Case Sensitive
  879.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  880.                            .getBytes();
  881.         // Searchable
  882.         rowVal[9] = s2b("true"); // Unsignable
  883.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  884.         rowVal[11] = s2b("true"); // Auto Increment
  885.         rowVal[12] = s2b("MEDIUMINT"); // Locale Type Name
  886.         rowVal[13] = s2b("0"); // Minimum Scale
  887.         rowVal[14] = s2b("0"); // Maximum Scale
  888.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  889.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  890.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  891.         tuples.add(rowVal);
  892.         /*
  893.          * MySQL Type: SMALLINT
  894.          * JDBC  Type: SMALLINT
  895.          */
  896.         rowVal = new byte[18][];
  897.         rowVal[0] = s2b("SMALLINT");
  898.         rowVal[1] = Integer.toString(java.sql.Types.SMALLINT).getBytes();
  899.         // JDBC Data type
  900.         rowVal[2] = s2b("5"); // Precision
  901.         rowVal[3] = s2b(""); // Literal Prefix
  902.         rowVal[4] = s2b(""); // Literal Suffix
  903.         rowVal[5] = s2b("[(M)] [UNSIGNED] [ZEROFILL]"); // Create Params
  904.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  905.                            .getBytes();
  906.         // Nullable
  907.         rowVal[7] = s2b("false"); // Case Sensitive
  908.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  909.                            .getBytes();
  910.         // Searchable
  911.         rowVal[9] = s2b("true"); // Unsignable
  912.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  913.         rowVal[11] = s2b("true"); // Auto Increment
  914.         rowVal[12] = s2b("SMALLINT"); // Locale Type Name
  915.         rowVal[13] = s2b("0"); // Minimum Scale
  916.         rowVal[14] = s2b("0"); // Maximum Scale
  917.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  918.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  919.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  920.         tuples.add(rowVal);
  921.         /*
  922.          * MySQL Type: DOUBLE
  923.          * JDBC  Type: FLOAT (is really an alias for DOUBLE from JDBC's perspective)
  924.          */
  925.         rowVal = new byte[18][];
  926.         rowVal[0] = s2b("DOUBLE");
  927.         rowVal[1] = Integer.toString(java.sql.Types.FLOAT).getBytes();
  928.         // JDBC Data type
  929.         rowVal[2] = s2b("17"); // Precision
  930.         rowVal[3] = s2b(""); // Literal Prefix
  931.         rowVal[4] = s2b(""); // Literal Suffix
  932.         rowVal[5] = s2b("[(M,D)] [ZEROFILL]"); // Create Params
  933.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  934.                            .getBytes();
  935.         // Nullable
  936.         rowVal[7] = s2b("false"); // Case Sensitive
  937.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  938.                            .getBytes();
  939.         // Searchable
  940.         rowVal[9] = s2b("false"); // Unsignable
  941.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  942.         rowVal[11] = s2b("true"); // Auto Increment
  943.         rowVal[12] = s2b("DOUBLE"); // Locale Type Name
  944.         rowVal[13] = s2b("-308"); // Minimum Scale
  945.         rowVal[14] = s2b("308"); // Maximum Scale
  946.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  947.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  948.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  949.         tuples.add(rowVal);
  950.         /*
  951.          * MySQL Type: FLOAT
  952.          * JDBC  Type: REAL (this is the SINGLE PERCISION floating point type)
  953.          */
  954.         rowVal = new byte[18][];
  955.         rowVal[0] = s2b("FLOAT");
  956.         rowVal[1] = Integer.toString(java.sql.Types.REAL).getBytes();
  957.         // JDBC Data type
  958.         rowVal[2] = s2b("10"); // Precision
  959.         rowVal[3] = s2b(""); // Literal Prefix
  960.         rowVal[4] = s2b(""); // Literal Suffix
  961.         rowVal[5] = s2b("[(M,D)] [ZEROFILL]"); // Create Params
  962.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  963.                            .getBytes();
  964.         // Nullable
  965.         rowVal[7] = s2b("false"); // Case Sensitive
  966.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  967.                            .getBytes();
  968.         // Searchable
  969.         rowVal[9] = s2b("false"); // Unsignable
  970.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  971.         rowVal[11] = s2b("true"); // Auto Increment
  972.         rowVal[12] = s2b("FLOAT"); // Locale Type Name
  973.         rowVal[13] = s2b("-38"); // Minimum Scale
  974.         rowVal[14] = s2b("38"); // Maximum Scale
  975.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  976.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  977.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  978.         tuples.add(rowVal);
  979.         /*
  980.          * MySQL Type: DOUBLE
  981.          * JDBC  Type: DOUBLE
  982.          */
  983.         rowVal = new byte[18][];
  984.         rowVal[0] = s2b("DOUBLE");
  985.         rowVal[1] = Integer.toString(java.sql.Types.DOUBLE).getBytes();
  986.         // JDBC Data type
  987.         rowVal[2] = s2b("17"); // Precision
  988.         rowVal[3] = s2b(""); // Literal Prefix
  989.         rowVal[4] = s2b(""); // Literal Suffix
  990.         rowVal[5] = s2b("[(M,D)] [ZEROFILL]"); // Create Params
  991.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  992.                            .getBytes();
  993.         // Nullable
  994.         rowVal[7] = s2b("false"); // Case Sensitive
  995.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  996.                            .getBytes();
  997.         // Searchable
  998.         rowVal[9] = s2b("false"); // Unsignable
  999.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1000.         rowVal[11] = s2b("true"); // Auto Increment
  1001.         rowVal[12] = s2b("DOUBLE"); // Locale Type Name
  1002.         rowVal[13] = s2b("-308"); // Minimum Scale
  1003.         rowVal[14] = s2b("308"); // Maximum Scale
  1004.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1005.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1006.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1007.         tuples.add(rowVal);
  1008.         /*
  1009.          * MySQL Type: DOUBLE PRECISION
  1010.          * JDBC  Type: DOUBLE
  1011.          */
  1012.         rowVal = new byte[18][];
  1013.         rowVal[0] = s2b("DOUBLE PRECISION");
  1014.         rowVal[1] = Integer.toString(java.sql.Types.DOUBLE).getBytes();
  1015.         // JDBC Data type
  1016.         rowVal[2] = s2b("17"); // Precision
  1017.         rowVal[3] = s2b(""); // Literal Prefix
  1018.         rowVal[4] = s2b(""); // Literal Suffix
  1019.         rowVal[5] = s2b("[(M,D)] [ZEROFILL]"); // Create Params
  1020.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1021.                            .getBytes();
  1022.         // Nullable
  1023.         rowVal[7] = s2b("false"); // Case Sensitive
  1024.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1025.                            .getBytes();
  1026.         // Searchable
  1027.         rowVal[9] = s2b("false"); // Unsignable
  1028.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1029.         rowVal[11] = s2b("true"); // Auto Increment
  1030.         rowVal[12] = s2b("DOUBLE PRECISION"); // Locale Type Name
  1031.         rowVal[13] = s2b("-308"); // Minimum Scale
  1032.         rowVal[14] = s2b("308"); // Maximum Scale
  1033.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1034.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1035.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1036.         tuples.add(rowVal);
  1037.         /*
  1038.          * MySQL Type: REAL (does not map to Types.REAL)
  1039.          * JDBC  Type: DOUBLE
  1040.          */
  1041.         rowVal = new byte[18][];
  1042.         rowVal[0] = s2b("REAL");
  1043.         rowVal[1] = Integer.toString(java.sql.Types.DOUBLE).getBytes();
  1044.         // JDBC Data type
  1045.         rowVal[2] = s2b("17"); // Precision
  1046.         rowVal[3] = s2b(""); // Literal Prefix
  1047.         rowVal[4] = s2b(""); // Literal Suffix
  1048.         rowVal[5] = s2b("[(M,D)] [ZEROFILL]"); // Create Params
  1049.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1050.                            .getBytes();
  1051.         // Nullable
  1052.         rowVal[7] = s2b("false"); // Case Sensitive
  1053.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1054.                            .getBytes();
  1055.         // Searchable
  1056.         rowVal[9] = s2b("false"); // Unsignable
  1057.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1058.         rowVal[11] = s2b("true"); // Auto Increment
  1059.         rowVal[12] = s2b("REAL"); // Locale Type Name
  1060.         rowVal[13] = s2b("-308"); // Minimum Scale
  1061.         rowVal[14] = s2b("308"); // Maximum Scale
  1062.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1063.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1064.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1065.         tuples.add(rowVal);
  1066.         /*
  1067.          * MySQL Type: VARCHAR
  1068.          * JDBC  Type: VARCHAR
  1069.          */
  1070.         rowVal = new byte[18][];
  1071.         rowVal[0] = s2b("VARCHAR");
  1072.         rowVal[1] = Integer.toString(java.sql.Types.VARCHAR).getBytes();
  1073.         // JDBC Data type
  1074.         rowVal[2] = s2b("255"); // Precision
  1075.         rowVal[3] = s2b("'"); // Literal Prefix
  1076.         rowVal[4] = s2b("'"); // Literal Suffix
  1077.         rowVal[5] = s2b("(M)"); // Create Params
  1078.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1079.                            .getBytes();
  1080.         // Nullable
  1081.         rowVal[7] = s2b("false"); // Case Sensitive
  1082.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1083.                            .getBytes();
  1084.         // Searchable
  1085.         rowVal[9] = s2b("false"); // Unsignable
  1086.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1087.         rowVal[11] = s2b("false"); // Auto Increment
  1088.         rowVal[12] = s2b("VARCHAR"); // Locale Type Name
  1089.         rowVal[13] = s2b("0"); // Minimum Scale
  1090.         rowVal[14] = s2b("0"); // Maximum Scale
  1091.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1092.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1093.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1094.         tuples.add(rowVal);
  1095.         /*
  1096.          * MySQL Type: ENUM
  1097.          * JDBC  Type: VARCHAR
  1098.          */
  1099.         rowVal = new byte[18][];
  1100.         rowVal[0] = s2b("ENUM");
  1101.         rowVal[1] = Integer.toString(java.sql.Types.VARCHAR).getBytes();
  1102.         // JDBC Data type
  1103.         rowVal[2] = s2b("65535"); // Precision
  1104.         rowVal[3] = s2b("'"); // Literal Prefix
  1105.         rowVal[4] = s2b("'"); // Literal Suffix
  1106.         rowVal[5] = s2b(""); // Create Params
  1107.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1108.                            .getBytes();
  1109.         // Nullable
  1110.         rowVal[7] = s2b("false"); // Case Sensitive
  1111.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1112.                            .getBytes();
  1113.         // Searchable
  1114.         rowVal[9] = s2b("false"); // Unsignable
  1115.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1116.         rowVal[11] = s2b("false"); // Auto Increment
  1117.         rowVal[12] = s2b("ENUM"); // Locale Type Name
  1118.         rowVal[13] = s2b("0"); // Minimum Scale
  1119.         rowVal[14] = s2b("0"); // Maximum Scale
  1120.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1121.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1122.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1123.         tuples.add(rowVal);
  1124.         /*
  1125.          * MySQL Type: SET
  1126.          * JDBC  Type: VARCHAR
  1127.          */
  1128.         rowVal = new byte[18][];
  1129.         rowVal[0] = s2b("SET");
  1130.         rowVal[1] = Integer.toString(java.sql.Types.VARCHAR).getBytes();
  1131.         // JDBC Data type
  1132.         rowVal[2] = s2b("64"); // Precision
  1133.         rowVal[3] = s2b("'"); // Literal Prefix
  1134.         rowVal[4] = s2b("'"); // Literal Suffix
  1135.         rowVal[5] = s2b(""); // Create Params
  1136.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1137.                            .getBytes();
  1138.         // Nullable
  1139.         rowVal[7] = s2b("false"); // Case Sensitive
  1140.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1141.                            .getBytes();
  1142.         // Searchable
  1143.         rowVal[9] = s2b("false"); // Unsignable
  1144.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1145.         rowVal[11] = s2b("false"); // Auto Increment
  1146.         rowVal[12] = s2b("SET"); // Locale Type Name
  1147.         rowVal[13] = s2b("0"); // Minimum Scale
  1148.         rowVal[14] = s2b("0"); // Maximum Scale
  1149.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1150.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1151.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1152.         tuples.add(rowVal);
  1153.         /*
  1154.          * MySQL Type: DATE
  1155.          * JDBC  Type: DATE
  1156.          */
  1157.         rowVal = new byte[18][];
  1158.         rowVal[0] = s2b("DATE");
  1159.         rowVal[1] = Integer.toString(java.sql.Types.DATE).getBytes();
  1160.         // JDBC Data type
  1161.         rowVal[2] = s2b("0"); // Precision
  1162.         rowVal[3] = s2b("'"); // Literal Prefix
  1163.         rowVal[4] = s2b("'"); // Literal Suffix
  1164.         rowVal[5] = s2b(""); // Create Params
  1165.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1166.                            .getBytes();
  1167.         // Nullable
  1168.         rowVal[7] = s2b("false"); // Case Sensitive
  1169.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1170.                            .getBytes();
  1171.         // Searchable
  1172.         rowVal[9] = s2b("false"); // Unsignable
  1173.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1174.         rowVal[11] = s2b("false"); // Auto Increment
  1175.         rowVal[12] = s2b("DATE"); // Locale Type Name
  1176.         rowVal[13] = s2b("0"); // Minimum Scale
  1177.         rowVal[14] = s2b("0"); // Maximum Scale
  1178.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1179.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1180.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1181.         tuples.add(rowVal);
  1182.         /*
  1183.          * MySQL Type: TIME
  1184.          * JDBC  Type: TIME
  1185.          */
  1186.         rowVal = new byte[18][];
  1187.         rowVal[0] = s2b("TIME");
  1188.         rowVal[1] = Integer.toString(java.sql.Types.TIME).getBytes();
  1189.         // JDBC Data type
  1190.         rowVal[2] = s2b("0"); // Precision
  1191.         rowVal[3] = s2b("'"); // Literal Prefix
  1192.         rowVal[4] = s2b("'"); // Literal Suffix
  1193.         rowVal[5] = s2b(""); // Create Params
  1194.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1195.                            .getBytes();
  1196.         // Nullable
  1197.         rowVal[7] = s2b("false"); // Case Sensitive
  1198.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1199.                            .getBytes();
  1200.         // Searchable
  1201.         rowVal[9] = s2b("false"); // Unsignable
  1202.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1203.         rowVal[11] = s2b("false"); // Auto Increment
  1204.         rowVal[12] = s2b("TIME"); // Locale Type Name
  1205.         rowVal[13] = s2b("0"); // Minimum Scale
  1206.         rowVal[14] = s2b("0"); // Maximum Scale
  1207.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1208.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1209.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1210.         tuples.add(rowVal);
  1211.         /*
  1212.          * MySQL Type: DATETIME
  1213.          * JDBC  Type: TIMESTAMP
  1214.          */
  1215.         rowVal = new byte[18][];
  1216.         rowVal[0] = s2b("DATETIME");
  1217.         rowVal[1] = Integer.toString(java.sql.Types.TIMESTAMP).getBytes();
  1218.         // JDBC Data type
  1219.         rowVal[2] = s2b("0"); // Precision
  1220.         rowVal[3] = s2b("'"); // Literal Prefix
  1221.         rowVal[4] = s2b("'"); // Literal Suffix
  1222.         rowVal[5] = s2b(""); // Create Params
  1223.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1224.                            .getBytes();
  1225.         // Nullable
  1226.         rowVal[7] = s2b("false"); // Case Sensitive
  1227.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1228.                            .getBytes();
  1229.         // Searchable
  1230.         rowVal[9] = s2b("false"); // Unsignable
  1231.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1232.         rowVal[11] = s2b("false"); // Auto Increment
  1233.         rowVal[12] = s2b("DATETIME"); // Locale Type Name
  1234.         rowVal[13] = s2b("0"); // Minimum Scale
  1235.         rowVal[14] = s2b("0"); // Maximum Scale
  1236.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1237.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1238.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1239.         tuples.add(rowVal);
  1240.         /*
  1241.          * MySQL Type: TIMESTAMP
  1242.          * JDBC  Type: TIMESTAMP
  1243.          */
  1244.         rowVal = new byte[18][];
  1245.         rowVal[0] = s2b("TIMESTAMP");
  1246.         rowVal[1] = Integer.toString(java.sql.Types.TIMESTAMP).getBytes();
  1247.         // JDBC Data type
  1248.         rowVal[2] = s2b("0"); // Precision
  1249.         rowVal[3] = s2b("'"); // Literal Prefix
  1250.         rowVal[4] = s2b("'"); // Literal Suffix
  1251.         rowVal[5] = s2b("[(M)]"); // Create Params
  1252.         rowVal[6] = Integer.toString(java.sql.DatabaseMetaData.typeNullable)
  1253.                            .getBytes();
  1254.         // Nullable
  1255.         rowVal[7] = s2b("false"); // Case Sensitive
  1256.         rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable)
  1257.                            .getBytes();
  1258.         // Searchable
  1259.         rowVal[9] = s2b("false"); // Unsignable
  1260.         rowVal[10] = s2b("false"); // Fixed Prec Scale
  1261.         rowVal[11] = s2b("false"); // Auto Increment
  1262.         rowVal[12] = s2b("TIMESTAMP"); // Locale Type Name
  1263.         rowVal[13] = s2b("0"); // Minimum Scale
  1264.         rowVal[14] = s2b("0"); // Maximum Scale
  1265.         rowVal[15] = s2b("0"); // SQL Data Type (not used)
  1266.         rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
  1267.         rowVal[17] = s2b("10"); //  NUM_PREC_RADIX (2 or 10)
  1268.         tuples.add(rowVal);
  1269.         return buildResultSet(fields, tuples);
  1270.     }
  1271.     /**
  1272.      * JDBC 2.0 Get a description of the user-defined types defined in a
  1273.      * particular schema.  Schema specific UDTs may have type JAVA_OBJECT,
  1274.      * STRUCT,  or DISTINCT.
  1275.      * 
  1276.      * <P>
  1277.      * Only types matching the catalog, schema, type name and type   criteria
  1278.      * are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM  and
  1279.      * TYPE_NAME.  The type name parameter may be a fully qualified  name. In
  1280.      * this case, the catalog and schemaPattern parameters are ignored.
  1281.      * </p>
  1282.      * 
  1283.      * <P>
  1284.      * Each type description has the following columns:
  1285.      * 
  1286.      * <OL>
  1287.      * <li>
  1288.      * <B>TYPE_CAT</B> String => the type's catalog (may be null)
  1289.      * </li>
  1290.      * <li>
  1291.      * <B>TYPE_SCHEM</B> String => type's schema (may be null)
  1292.      * </li>
  1293.      * <li>
  1294.      * <B>TYPE_NAME</B> String => type name
  1295.      * </li>
  1296.      * <li>
  1297.      * <B>CLASS_NAME</B> String => Java class name
  1298.      * </li>
  1299.      * <li>
  1300.      * <B>DATA_TYPE</B> String => type value defined in java.sql.Types.   One
  1301.      * of JAVA_OBJECT, STRUCT, or DISTINCT
  1302.      * </li>
  1303.      * <li>
  1304.      * <B>REMARKS</B> String => explanatory comment on the type
  1305.      * </li>
  1306.      * </ol>
  1307.      * </p>
  1308.      * 
  1309.      * <P>
  1310.      * <B>Note:</B> If the driver does not support UDTs then an empty result
  1311.      * set is returned.
  1312.      * </p>
  1313.      *
  1314.      * @param catalog a catalog name; "" retrieves those without a catalog;
  1315.      *        null means drop catalog name from the selection criteria
  1316.      * @param schemaPattern a schema name pattern; "" retrieves those without a
  1317.      *        schema
  1318.      * @param typeNamePattern a type name pattern; may be a fully qualified
  1319.      *        name
  1320.      * @param types a list of user-named types to include (JAVA_OBJECT, STRUCT,
  1321.      *        or DISTINCT); null returns all types
  1322.      *
  1323.      * @return ResultSet - each row is a type description
  1324.      *
  1325.      * @exception SQLException if a database-access error occurs.
  1326.      */
  1327.     public java.sql.ResultSet getUDTs(String catalog, String schemaPattern,
  1328.         String typeNamePattern, int[] types) throws SQLException {
  1329.         Field[] fields = new Field[6];
  1330.         fields[0] = new Field("", "TYPE_CAT", Types.VARCHAR, 32);
  1331.         fields[1] = new Field("", "TYPE_SCHEM", Types.VARCHAR, 32);
  1332.         fields[2] = new Field("", "TYPE_NAME", Types.VARCHAR, 32);
  1333.         fields[3] = new Field("", "CLASS_NAME", Types.VARCHAR, 32);
  1334.         fields[4] = new Field("", "DATA_TYPE", Types.VARCHAR, 32);
  1335.         fields[5] = new Field("", "REMARKS", Types.VARCHAR, 32);
  1336.         ArrayList tuples = new ArrayList();
  1337.         return buildResultSet(fields, tuples);
  1338.     }
  1339.     /**
  1340.      * What's the url for this database?
  1341.      *
  1342.      * @return the url or null if it can't be generated
  1343.      *
  1344.      * @throws java.sql.SQLException DOCUMENT ME!
  1345.      */
  1346.     public String getURL() throws java.sql.SQLException {
  1347.         return this.conn.getURL();
  1348.     }
  1349.     /**
  1350.      * What's our user name as known to the database?
  1351.      *
  1352.      * @return our database user name
  1353.      *
  1354.      * @throws java.sql.SQLException DOCUMENT ME!
  1355.      */
  1356.     public String getUserName() throws java.sql.SQLException {
  1357.         if (this.conn.useHostsInPrivileges()) {
  1358.             Statement stmt = null;
  1359.             ResultSet rs = null;
  1360.             try {
  1361.                 stmt = this.conn.createStatement();
  1362.                 
  1363. if (stmt.getMaxRows() != 0) {
  1364. stmt.setMaxRows(0);
  1365. }
  1366.                 rs = stmt.executeQuery("SELECT USER()");
  1367.                 rs.next();
  1368.                 return rs.getString(1);
  1369.             } finally {
  1370.                 if (rs != null) {
  1371.                     try {
  1372.                         rs.close();
  1373.                     } catch (Exception ex) {
  1374.                         AssertionFailedException.shouldNotHappen(ex);
  1375.                     }
  1376.                     rs = null;
  1377.                 }
  1378.                 if (stmt != null) {
  1379.                     try {
  1380.                         stmt.close();
  1381.                     } catch (Exception ex) {
  1382.                         AssertionFailedException.shouldNotHappen(ex);
  1383.                     }
  1384.                     stmt = null;
  1385.                 }
  1386.             }
  1387.         } else {
  1388.             return this.conn.getUser();
  1389.         }
  1390.     }
  1391.     /**
  1392.      * Get a description of a table's columns that are automatically updated
  1393.      * when any value in a row is updated.  They are unordered.
  1394.      * 
  1395.      * <P>
  1396.      * Each column description has the following columns:
  1397.      * 
  1398.      * <OL>
  1399.      * <li>
  1400.      * <B>SCOPE</B> short => is not used
  1401.      * </li>
  1402.      * <li>
  1403.      * <B>COLUMN_NAME</B> String => column name
  1404.      * </li>
  1405.      * <li>
  1406.      * <B>DATA_TYPE</B> short => SQL data type from java.sql.Types
  1407.      * </li>
  1408.      * <li>
  1409.      * <B>TYPE_NAME</B> String => Data source dependent type name
  1410.      * </li>
  1411.      * <li>
  1412.      * <B>COLUMN_SIZE</B> int => precision
  1413.      * </li>
  1414.      * <li>
  1415.      * <B>BUFFER_LENGTH</B> int => length of column value in bytes
  1416.      * </li>
  1417.      * <li>
  1418.      * <B>DECIMAL_DIGITS</B> short  => scale
  1419.      * </li>
  1420.      * <li>
  1421.      * <B>PSEUDO_COLUMN</B> short => is this a pseudo column like an Oracle
  1422.      * ROWID
  1423.      * 
  1424.      * <UL>
  1425.      * <li>
  1426.      * versionColumnUnknown - may or may not be pseudo column
  1427.      * </li>
  1428.      * <li>
  1429.      * versionColumnNotPseudo - is NOT a pseudo column
  1430.      * </li>
  1431.      * <li>
  1432.      * versionColumnPseudo - is a pseudo column
  1433.      * </li>
  1434.      * </ul>
  1435.      * 
  1436.      * </li>
  1437.      * </ol>
  1438.      * </p>
  1439.      *
  1440.      * @param catalog a catalog name; "" retrieves those without a catalog
  1441.      * @param schema a schema name; "" retrieves those without a schema
  1442.      * @param table a table name
  1443.      *
  1444.      * @return ResultSet each row is a column description
  1445.      *
  1446.      * @throws java.sql.SQLException DOCUMENT ME!
  1447.      */
  1448.     public java.sql.ResultSet getVersionColumns(String catalog, String schema,
  1449.         String table) throws java.sql.SQLException {
  1450.         Field[] fields = new Field[8];
  1451.         fields[0] = new Field("", "SCOPE", Types.SMALLINT, 5);
  1452.         fields[1] = new Field("", "COLUMN_NAME", Types.CHAR, 32);
  1453.         fields[2] = new Field("", "DATA_TYPE", Types.SMALLINT, 5);
  1454.         fields[3] = new Field("", "TYPE_NAME", Types.CHAR, 16);
  1455.         fields[4] = new Field("", "COLUMN_SIZE", Types.CHAR, 16);
  1456.         fields[5] = new Field("", "BUFFER_LENGTH", Types.CHAR, 16);
  1457.         fields[6] = new Field("", "DECIMAL_DIGITS", Types.CHAR, 16);
  1458.         fields[7] = new Field("", "PSEUDO_COLUMN", Types.SMALLINT, 5);
  1459.         return buildResultSet(fields, new ArrayList());
  1460.         // do TIMESTAMP columns count?
  1461.     }
  1462.     /**
  1463.      * Can all the procedures returned by getProcedures be called by the
  1464.      * current user?
  1465.      *
  1466.      * @return true if so
  1467.      *
  1468.      * @throws java.sql.SQLException DOCUMENT ME!
  1469.      */
  1470.     public boolean allProceduresAreCallable() throws java.sql.SQLException {
  1471.         return false;
  1472.     }
  1473.     /**
  1474.      * Can all the tables returned by getTable be SELECTed by the current user?
  1475.      *
  1476.      * @return true if so
  1477.      *
  1478.      * @throws java.sql.SQLException DOCUMENT ME!
  1479.      */
  1480.     public boolean allTablesAreSelectable() throws java.sql.SQLException {
  1481.         return false;
  1482.     }
  1483.     /**
  1484.      * Does a data definition statement within a transaction force the
  1485.      * transaction to commit?
  1486.      *
  1487.      * @return true if so
  1488.      *
  1489.      * @throws java.sql.SQLException DOCUMENT ME!
  1490.      */
  1491.     public boolean dataDefinitionCausesTransactionCommit()
  1492.         throws java.sql.SQLException {
  1493.         return true;
  1494.     }
  1495.     /**
  1496.      * Is a data definition statement within a transaction ignored?
  1497.      *
  1498.      * @return true if so
  1499.      *
  1500.      * @throws java.sql.SQLException DOCUMENT ME!
  1501.      */
  1502.     public boolean dataDefinitionIgnoredInTransactions()
  1503.         throws java.sql.SQLException {
  1504.         return false;
  1505.     }
  1506.     /**
  1507.      * JDBC 2.0 Determine whether or not a visible row delete can be detected
  1508.      * by  calling ResultSet.rowDeleted().  If deletesAreDetected() returns
  1509.      * false, then deleted rows are removed from the result set.
  1510.      *
  1511.      * @param type set type, i.e. ResultSet.TYPE_XXX
  1512.      *
  1513.      * @return true if changes are detected by the resultset type
  1514.      *
  1515.      * @exception SQLException if a database-access error occurs.
  1516.      */
  1517.     public boolean deletesAreDetected(int type) throws SQLException {
  1518.         return false;
  1519.     }
  1520.     /**
  1521.      * Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY blobs?
  1522.      *
  1523.      * @return true if so
  1524.      *
  1525.      * @throws java.sql.SQLException DOCUMENT ME!
  1526.      */
  1527.     public boolean doesMaxRowSizeIncludeBlobs() throws java.sql.SQLException {
  1528.         return true;
  1529.     }
  1530.     /**
  1531.      * Extracts foreign key info for one table.
  1532.      *
  1533.      * @param rows the list of rows to add to
  1534.      * @param rs the result set from 'SHOW CREATE TABLE'
  1535.      * @param catalog the database name
  1536.      *
  1537.      * @return the list of rows with new rows added
  1538.      *
  1539.      * @throws SQLException if a database access error occurs
  1540.      */
  1541.     public List extractForeignKeyForTable(ArrayList rows,
  1542.         java.sql.ResultSet rs, String catalog) throws SQLException {
  1543.         byte[][] row = new byte[3][];
  1544.         row[0] = rs.getBytes(1);
  1545.         row[1] = s2b(SUPPORTS_FK);
  1546.         String createTableString = rs.getString(2);
  1547.         StringTokenizer lineTokenizer = new StringTokenizer(createTableString,
  1548.                 "n");
  1549.         StringBuffer commentBuf = new StringBuffer("comment; ");
  1550.         boolean firstTime = true;
  1551.         while (lineTokenizer.hasMoreTokens()) {
  1552.             String line = lineTokenizer.nextToken().trim();
  1553.             String constraintName = null;
  1554.             if (StringUtils.startsWithIgnoreCase(line, "CONSTRAINT")) {
  1555.                 boolean usingBackTicks = true;
  1556.                 int beginPos = line.indexOf("`");
  1557.                 if (beginPos == -1) {
  1558.                     beginPos = line.indexOf(""");
  1559.                     usingBackTicks = false;
  1560.                 }
  1561.                 if (beginPos != -1) {
  1562.                     int endPos = -1;
  1563.                     if (usingBackTicks) {
  1564.                         endPos = line.indexOf("`", beginPos + 1);
  1565.                     } else {
  1566.                         endPos = line.indexOf(""", beginPos + 1);
  1567.                     }
  1568.                     if (endPos != -1) {
  1569.                         constraintName = line.substring(beginPos + 1, endPos);
  1570.                         line = line.substring(endPos + 1, line.length()).trim();
  1571.                     }
  1572.                 }
  1573.             }
  1574.             if (line.startsWith("FOREIGN KEY")) {
  1575.                 if (line.endsWith(",")) {
  1576.                     line = line.substring(0, line.length() - 1);
  1577.                 }
  1578.                 // Remove all back-ticks
  1579.                 int lineLength = line.length();
  1580.                 StringBuffer lineBuf = new StringBuffer(lineLength);
  1581.                 for (int i = 0; i < lineLength; i++) {
  1582.                     char c = line.charAt(i);
  1583.                     if (c != '`') {
  1584.                         lineBuf.append(c);
  1585.                     }
  1586.                 }
  1587.                 line = lineBuf.toString();
  1588.                 StringTokenizer keyTokens = new StringTokenizer(line, "()",
  1589.                         false);
  1590.                 keyTokens.nextToken(); // eat 'FOREIGN KEY'
  1591.                 String localColumnNamesString = keyTokens.nextToken();
  1592.                 String referCatalogTableString = keyTokens.nextToken();
  1593.                 StringTokenizer referSchemaTable = new StringTokenizer(referCatalogTableString
  1594.                         .trim(), " .");
  1595.                 String referColumnNamesString = keyTokens.nextToken();
  1596.                 referSchemaTable.nextToken(); //discard the REFERENCES token
  1597.                 int numTokensLeft = referSchemaTable.countTokens();
  1598.                 String referCatalog = null;
  1599.                 String referTable = null;
  1600.                 if (numTokensLeft == 2) {
  1601.                     // some versions of MySQL don't report the database name
  1602.                     referCatalog = referSchemaTable.nextToken();
  1603.                     referTable = referSchemaTable.nextToken();
  1604.                 } else {
  1605.                     referTable = referSchemaTable.nextToken();
  1606.                     referCatalog = catalog;
  1607.                 }
  1608.                 if (!firstTime) {
  1609.                     commentBuf.append("; ");
  1610.                 } else {
  1611.                     firstTime = false;
  1612.                 }
  1613.                 if (constraintName != null) {
  1614.                     commentBuf.append(constraintName);
  1615.                 } else {
  1616.                     commentBuf.append("not_available");
  1617.                 }
  1618.                 commentBuf.append("(");
  1619.                 commentBuf.append(localColumnNamesString);
  1620.                 commentBuf.append(") REFER ");
  1621.                 commentBuf.append(referCatalog);
  1622.                 commentBuf.append("/");
  1623.                 commentBuf.append(referTable);
  1624.                 commentBuf.append("(");
  1625.                 commentBuf.append(referColumnNamesString);
  1626.                 commentBuf.append(")");
  1627.                 int lastParenIndex = line.lastIndexOf(")");
  1628.                 if (lastParenIndex != (line.length() - 1)) {
  1629.                     String cascadeOptions = cascadeOptions = line.substring(lastParenIndex
  1630.                                 + 1);
  1631.                     commentBuf.append(" ");
  1632.                     commentBuf.append(cascadeOptions);
  1633.                 }
  1634.             }
  1635.         }
  1636.         row[2] = s2b(commentBuf.toString());
  1637.         rows.add(row);
  1638.         return rows;
  1639.     }
  1640.     /**
  1641.      * Creates a result set similar enough to 'SHOW TABLE STATUS' to allow the
  1642.      * same code to work on extracting the foreign key data
  1643.      *
  1644.      * @param conn the database connection to use
  1645.      * @param metadata the DatabaseMetaData instance calling this method
  1646.      * @param catalog the database name to extract foreign key info for
  1647.      * @param tableName the table to extract foreign key info for
  1648.      *
  1649.      * @return A result set that has the structure of 'show table status'
  1650.      *
  1651.      * @throws SQLException if a database access error occurs.
  1652.      */
  1653.     public ResultSet extractForeignKeyFromCreateTable(
  1654.         java.sql.Connection conn, java.sql.DatabaseMetaData metadata,
  1655.         String catalog, String tableName) throws SQLException {
  1656.         ArrayList tableList = new ArrayList();
  1657.         java.sql.ResultSet rs = null;
  1658.         java.sql.Statement stmt = null;
  1659.         if (tableName != null) {
  1660.             tableList.add(tableName);
  1661.         } else {
  1662.             try {
  1663.                 rs = metadata.getTables(catalog, "", "%",
  1664.                         new String[] { "TABLE" });
  1665.                 while (rs.next()) {
  1666.                     tableList.add(rs.getString("TABLE_NAME"));
  1667.                 }
  1668.             } finally {
  1669.                 if (rs != null) {
  1670.                     rs.close();
  1671.                 }
  1672.                 rs = null;
  1673.             }
  1674.         }
  1675.         ArrayList rows = new ArrayList();
  1676.         Field[] fields = new Field[3];
  1677.         fields[0] = new Field("", "Name", Types.CHAR, Integer.MAX_VALUE);
  1678.         fields[1] = new Field("", "Type", Types.CHAR, 255);
  1679.         fields[2] = new Field("", "Comment", Types.CHAR, Integer.MAX_VALUE);
  1680.         int numTables = tableList.size();
  1681.         try {
  1682.             stmt = conn.createStatement();
  1683.             
  1684.             if (stmt.getMaxRows() != 0) {
  1685.              stmt.setMaxRows(0);
  1686.             }
  1687.             for (int i = 0; i < numTables; i++) {
  1688.                 String tableToExtract = (String) tableList.get(i);
  1689.                 String query = new StringBuffer("SHOW CREATE TABLE ").append(
  1690.                         "`").append(catalog).append("`.`").append(tableToExtract)
  1691.                                                                      .append("`")
  1692.                                                                      .toString();
  1693.                 rs = stmt.executeQuery(query);
  1694.                 while (rs.next()) {
  1695.                     extractForeignKeyForTable(rows, rs, catalog);
  1696.                 }
  1697.             }
  1698.         } finally {
  1699.             if (rs != null) {
  1700.                 rs.close();
  1701.             }
  1702.             rs = null;
  1703.             if (stmt != null) {
  1704.                 stmt.close();
  1705.             }
  1706.             stmt = null;
  1707.         }
  1708.         return buildResultSet(fields, rows);
  1709.     }
  1710.     /**
  1711.      * JDBC 2.0 Determine whether or not a visible row insert can be detected
  1712.      * by calling ResultSet.rowInserted().
  1713.      *
  1714.      * @param type set type, i.e. ResultSet.TYPE_XXX
  1715.      *
  1716.      * @return true if changes are detected by the resultset type
  1717.      *
  1718.      * @exception SQLException if a database-access error occurs.
  1719.      */
  1720.     public boolean insertsAreDetected(int type) throws SQLException {
  1721.         return false;
  1722.     }
  1723.     /**
  1724.      * @see DatabaseMetaData#locatorsUpdateCopy()
  1725.      */
  1726.     public boolean locatorsUpdateCopy() throws SQLException {
  1727.         return true;
  1728.     }
  1729.     /**
  1730.      * Are concatenations between NULL and non-NULL values NULL? A JDBC
  1731.      * compliant driver always returns true.
  1732.      *
  1733.      * @return true if so
  1734.      *
  1735.      * @throws java.sql.SQLException DOCUMENT ME!
  1736.      */
  1737.     public boolean nullPlusNonNullIsNull() throws java.sql.SQLException {
  1738.         return true;
  1739.     }
  1740.     /**
  1741.      * Are NULL values sorted at the end regardless of sort order?
  1742.      *
  1743.      * @return true if so
  1744.      *
  1745.      * @throws java.sql.SQLException DOCUMENT ME!
  1746.      */
  1747.     public boolean nullsAreSortedAtEnd() throws java.sql.SQLException {
  1748.         return false;
  1749.     }
  1750.     /**
  1751.      * Are NULL values sorted at the start regardless of sort order?
  1752.      *
  1753.      * @return true if so
  1754.      *
  1755.      * @throws java.sql.SQLException DOCUMENT ME!
  1756.      */
  1757.     public boolean nullsAreSortedAtStart() throws java.sql.SQLException {
  1758.         if (this.conn.getIO().versionMeetsMinimum(4, 0, 2)
  1759.                 && !this.conn.getIO().versionMeetsMinimum(4, 0, 11)) {
  1760.             return true;
  1761.         } else {
  1762.             return false;
  1763.         }
  1764.     }
  1765.     /**
  1766.      * Are NULL values sorted high?
  1767.      *
  1768.      * @return true if so
  1769.      *
  1770.      * @throws java.sql.SQLException DOCUMENT ME!
  1771.      */
  1772.     public boolean nullsAreSortedHigh() throws java.sql.SQLException {
  1773.         return false;
  1774.     }
  1775.     /**
  1776.      * Are NULL values sorted low?
  1777.      *
  1778.      * @return true if so
  1779.      *
  1780.      * @throws java.sql.SQLException DOCUMENT ME!
  1781.      */
  1782.     public boolean nullsAreSortedLow() throws java.sql.SQLException {
  1783.         return !nullsAreSortedHigh();
  1784.     }
  1785.     /**
  1786.      * DOCUMENT ME!
  1787.      *
  1788.      * @param type DOCUMENT ME!
  1789.      *
  1790.      * @return DOCUMENT ME!
  1791.      *
  1792.      * @throws SQLException DOCUMENT ME!
  1793.      */
  1794.     public boolean othersDeletesAreVisible(int type) throws SQLException {
  1795.         return false;
  1796.     }
  1797.     /**
  1798.      * DOCUMENT ME!
  1799.      *
  1800.      * @param type DOCUMENT ME!
  1801.      *
  1802.      * @return DOCUMENT ME!
  1803.      *
  1804.      * @throws SQLException DOCUMENT ME!
  1805.      */
  1806.     public boolean othersInsertsAreVisible(int type) throws SQLException {
  1807.         return false;
  1808.     }
  1809.     /**
  1810.      * JDBC 2.0 Determine whether changes made by others are visible.
  1811.      *
  1812.      * @param type set type, i.e. ResultSet.TYPE_XXX
  1813.      *
  1814.      * @return true if changes are visible for the result set type
  1815.      *
  1816.      * @exception SQLException if a database-access error occurs.
  1817.      */
  1818.     public boolean othersUpdatesAreVisible(int type) throws SQLException {
  1819.         return false;
  1820.     }
  1821.     /**
  1822.      * DOCUMENT ME!
  1823.      *
  1824.      * @param type DOCUMENT ME!
  1825.      *
  1826.      * @return DOCUMENT ME!
  1827.      *
  1828.      * @throws SQLException DOCUMENT ME!
  1829.      */
  1830.     public boolean ownDeletesAreVisible(int type) throws SQLException {
  1831.         return false;
  1832.     }
  1833.     /**
  1834.      * DOCUMENT ME!
  1835.      *
  1836.      * @param type DOCUMENT ME!
  1837.      *
  1838.      * @return DOCUMENT ME!
  1839.      *
  1840.      * @throws SQLException DOCUMENT ME!
  1841.      */
  1842.     public boolean ownInsertsAreVisible(int type) throws SQLException {
  1843.         return false;
  1844.     }
  1845.     /**
  1846.      * JDBC 2.0 Determine whether a result set's own changes visible.
  1847.      *
  1848.      * @param type set type, i.e. ResultSet.TYPE_XXX
  1849.      *
  1850.      * @return true if changes are visible for the result set type
  1851.      *
  1852.      * @exception SQLException if a database-access error occurs.
  1853.      */
  1854.     public boolean ownUpdatesAreVisible(int type) throws SQLException {
  1855.         return false;
  1856.     }
  1857.     /**
  1858.      * Does the database store mixed case unquoted SQL identifiers in lower
  1859.      * case?
  1860.      *
  1861.      * @return true if so
  1862.      *
  1863.      * @throws java.sql.SQLException DOCUMENT ME!
  1864.      */
  1865.     public boolean storesLowerCaseIdentifiers() throws java.sql.SQLException {
  1866.         return false;
  1867.     }
  1868.     /**
  1869.      * Does the database store mixed case quoted SQL identifiers in lower case?
  1870.      * A JDBC compliant driver will always return false.
  1871.      *
  1872.      * @return true if so
  1873.      *
  1874.      * @throws java.sql.SQLException DOCUMENT ME!
  1875.      */
  1876.     public boolean storesLowerCaseQuotedIdentifiers()
  1877.         throws java.sql.SQLException {
  1878.         return false;
  1879.     }
  1880.     /**
  1881.      * Does the database store mixed case unquoted SQL identifiers in mixed
  1882.      * case?
  1883.      *
  1884.      * @return true if so
  1885.      *
  1886.      * @throws java.sql.SQLException DOCUMENT ME!
  1887.      */
  1888.     public boolean storesMixedCaseIdentifiers() throws java.sql.SQLException {
  1889.         return true;
  1890.     }
  1891.     /**
  1892.      * Does the database store mixed case quoted SQL identifiers in mixed case?
  1893.      * A JDBC compliant driver will always return false.
  1894.      *
  1895.      * @return true if so
  1896.      *
  1897.      * @throws java.sql.SQLException DOCUMENT ME!
  1898.      */
  1899.     public boolean storesMixedCaseQuotedIdentifiers()
  1900.         throws java.sql.SQLException {
  1901.         return false;
  1902.     }
  1903.     /**
  1904.      * Does the database store mixed case unquoted SQL identifiers in upper
  1905.      * case?
  1906.      *
  1907.      * @return true if so
  1908.      *
  1909.      * @throws java.sql.SQLException DOCUMENT ME!
  1910.      */
  1911.     public boolean storesUpperCaseIdentifiers() throws java.sql.SQLException {
  1912.         return false;
  1913.     }
  1914.     /**
  1915.      * Does the database store mixed case quoted SQL identifiers in upper case?
  1916.      * A JDBC compliant driver will always return true.
  1917.      *
  1918.      * @return true if so
  1919.      *
  1920.      * @throws java.sql.SQLException DOCUMENT ME!
  1921.      */
  1922.     public boolean storesUpperCaseQuotedIdentifiers()
  1923.         throws java.sql.SQLException {
  1924.         return false;
  1925.     }
  1926.     /**
  1927.      * Is the ANSI92 entry level SQL grammar supported? All JDBC compliant
  1928.      * drivers must return true.
  1929.      *
  1930.      * @return true if so
  1931.      *
  1932.      * @throws java.sql.SQLException DOCUMENT ME!
  1933.      */
  1934.     public boolean supportsANSI92EntryLevelSQL() throws java.sql.SQLException {
  1935.         return true;
  1936.     }
  1937.     /**
  1938.      * Is the ANSI92 full SQL grammar supported?
  1939.      *
  1940.      * @return true if so
  1941.      *
  1942.      * @throws java.sql.SQLException DOCUMENT ME!
  1943.      */
  1944.     public boolean supportsANSI92FullSQL() throws java.sql.SQLException {
  1945.         return false;
  1946.     }
  1947.     /**
  1948.      * Is the ANSI92 intermediate SQL grammar supported?
  1949.      *
  1950.      * @return true if so
  1951.      *
  1952.      * @throws java.sql.SQLException DOCUMENT ME!
  1953.      */
  1954.     public boolean supportsANSI92IntermediateSQL() throws java.sql.SQLException {
  1955.         return false;
  1956.     }
  1957.     /**
  1958.      * Is "ALTER TABLE" with add column supported?
  1959.      *
  1960.      * @return true if so
  1961.      *
  1962.      * @throws java.sql.SQLException DOCUMENT ME!
  1963.      */
  1964.     public boolean supportsAlterTableWithAddColumn()
  1965.         throws java.sql.SQLException {
  1966.         return true;
  1967.     }
  1968.     /**
  1969.      * Is "ALTER TABLE" with drop column supported?
  1970.      *
  1971.      * @return true if so
  1972.      *
  1973.      * @throws java.sql.SQLException DOCUMENT ME!
  1974.      */
  1975.     public boolean supportsAlterTableWithDropColumn()
  1976.         throws java.sql.SQLException {
  1977.         return true;
  1978.     }
  1979.     /**
  1980.      * JDBC 2.0 Return true if the driver supports batch updates, else return
  1981.      * false.
  1982.      *
  1983.      * @return DOCUMENT ME!
  1984.      *
  1985.      * @throws SQLException DOCUMENT ME!
  1986.      */
  1987.     public boolean supportsBatchUpdates() throws SQLException {
  1988.         return true;
  1989.     }
  1990.     /**
  1991.      * Can a catalog name be used in a data manipulation statement?
  1992.      *
  1993.      * @return true if so
  1994.      *
  1995.      * @throws java.sql.SQLException DOCUMENT ME!
  1996.      */
  1997.     public boolean supportsCatalogsInDataManipulation()
  1998.         throws java.sql.SQLException {
  1999.         // Servers before 3.22 could not do this
  2000.         return this.conn.getIO().versionMeetsMinimum(3, 3, 22);
  2001.     }
  2002.     /**
  2003.      * Can a catalog name be used in a index definition statement?
  2004.      *
  2005.      * @return true if so
  2006.      *
  2007.      * @throws java.sql.SQLException DOCUMENT ME!
  2008.      */
  2009.     public boolean supportsCatalogsInIndexDefinitions()
  2010.         throws java.sql.SQLException {
  2011.         return false;
  2012.     }
  2013.     /**
  2014.      * Can a catalog name be used in a privilege definition statement?
  2015.      *
  2016.      * @return true if so
  2017.      *
  2018.      * @throws java.sql.SQLException DOCUMENT ME!
  2019.      */
  2020.     public boolean supportsCatalogsInPrivilegeDefinitions()
  2021.         throws java.sql.SQLException {
  2022.         return false;
  2023.     }
  2024.     /**
  2025.      * Can a catalog name be used in a procedure call statement?
  2026.      *
  2027.      * @return true if so
  2028.      *
  2029.      * @throws java.sql.SQLException DOCUMENT ME!
  2030.      */
  2031.     public boolean supportsCatalogsInProcedureCalls()
  2032.         throws java.sql.SQLException {
  2033.         return false;
  2034.     }
  2035.     /**
  2036.      * Can a catalog name be used in a table definition statement?
  2037.      *
  2038.      * @return true if so
  2039.      *
  2040.      * @throws java.sql.SQLException DOCUMENT ME!
  2041.      */
  2042.     public boolean supportsCatalogsInTableDefinitions()
  2043.         throws java.sql.SQLException {
  2044.         return false;
  2045.     }
  2046.     /**
  2047.      * Is column aliasing supported?
  2048.      * 
  2049.      * <P>
  2050.      * If so, the SQL AS clause can be used to provide names for computed
  2051.      * columns or to provide alias names for columns as required. A JDBC
  2052.      * compliant driver always returns true.
  2053.      * </p>
  2054.      *
  2055.      * @return true if so
  2056.      *
  2057.      * @throws java.sql.SQLException DOCUMENT ME!
  2058.      */
  2059.     public boolean supportsColumnAliasing() throws java.sql.SQLException {
  2060.         return true;
  2061.     }
  2062.     /**
  2063.      * Is the CONVERT function between SQL types supported?
  2064.      *
  2065.      * @return true if so
  2066.      *
  2067.      * @throws java.sql.SQLException DOCUMENT ME!
  2068.      */
  2069.     public boolean supportsConvert() throws java.sql.SQLException {
  2070.         return true;
  2071.     }
  2072.     /**
  2073.  * Is CONVERT between the given SQL types supported?
  2074.  *
  2075.  * @param fromType the type to convert from
  2076.  * @param toType the type to convert to
  2077.  *
  2078.  * @return true if so
  2079.  *
  2080.  * @throws java.sql.SQLException if an error occurs
  2081.  *
  2082.  * @see Types
  2083.  */
  2084. public boolean supportsConvert(int fromType, int toType)
  2085.     throws java.sql.SQLException {
  2086.     switch (fromType) {
  2087.     /* The char/binary types can be converted
  2088.      * to pretty much anything.
  2089.      */
  2090.     case java.sql.Types.CHAR:
  2091.     case java.sql.Types.VARCHAR:
  2092.     case java.sql.Types.LONGVARCHAR:
  2093.     case java.sql.Types.BINARY:
  2094.     case java.sql.Types.VARBINARY:
  2095.     case java.sql.Types.LONGVARBINARY:
  2096.         switch (toType) {
  2097.         case java.sql.Types.DECIMAL:
  2098.         case java.sql.Types.NUMERIC:
  2099.         case java.sql.Types.REAL:
  2100.         case java.sql.Types.TINYINT:
  2101.         case java.sql.Types.SMALLINT:
  2102.         case java.sql.Types.INTEGER:
  2103.         case java.sql.Types.BIGINT:
  2104.         case java.sql.Types.FLOAT:
  2105.         case java.sql.Types.DOUBLE:
  2106.         case java.sql.Types.CHAR:
  2107.         case java.sql.Types.VARCHAR:
  2108.         case java.sql.Types.LONGVARCHAR:
  2109.         case java.sql.Types.BINARY:
  2110.         case java.sql.Types.VARBINARY:
  2111.         case java.sql.Types.LONGVARBINARY:
  2112.         case java.sql.Types.OTHER:
  2113.         case java.sql.Types.DATE:
  2114.         case java.sql.Types.TIME:
  2115.         case java.sql.Types.TIMESTAMP:
  2116.             return true;
  2117.         default:
  2118.             return false;
  2119.         }
  2120.     /* We don't handle the BIT type
  2121.      * yet.
  2122.      */
  2123.     case java.sql.Types.BIT:
  2124.         return false;
  2125.     /* The numeric types. Basically they can convert
  2126.      * among themselves, and with char/binary types.
  2127.      */
  2128.     case java.sql.Types.DECIMAL:
  2129.     case java.sql.Types.NUMERIC:
  2130.     case java.sql.Types.REAL:
  2131.     case java.sql.Types.TINYINT:
  2132.     case java.sql.Types.SMALLINT:
  2133.     case java.sql.Types.INTEGER:
  2134.     case java.sql.Types.BIGINT:
  2135.     case java.sql.Types.FLOAT:
  2136.     case java.sql.Types.DOUBLE:
  2137.         switch (toType) {
  2138.         case java.sql.Types.DECIMAL:
  2139.         case java.sql.Types.NUMERIC:
  2140.         case java.sql.Types.REAL:
  2141.         case java.sql.Types.TINYINT:
  2142.         case java.sql.Types.SMALLINT:
  2143.         case java.sql.Types.INTEGER:
  2144.         case java.sql.Types.BIGINT:
  2145.         case java.sql.Types.FLOAT:
  2146.         case java.sql.Types.DOUBLE:
  2147.         case java.sql.Types.CHAR:
  2148.         case java.sql.Types.VARCHAR:
  2149.         case java.sql.Types.LONGVARCHAR:
  2150.         case java.sql.Types.BINARY:
  2151.         case java.sql.Types.VARBINARY:
  2152.         case java.sql.Types.LONGVARBINARY:
  2153.             return true;
  2154.         default:
  2155.             return false;
  2156.         }
  2157.     /* MySQL doesn't support a NULL type. */
  2158.     case java.sql.Types.NULL:
  2159.         return false;
  2160.     /* With this driver, this will always be a serialized
  2161.      * object, so the char/binary types will work.
  2162.      */
  2163.     case java.sql.Types.OTHER:
  2164.         switch (toType) {
  2165.         case java.sql.Types.CHAR:
  2166.         case java.sql.Types.VARCHAR:
  2167.         case java.sql.Types.LONGVARCHAR:
  2168.         case java.sql.Types.BINARY:
  2169.         case java.sql.Types.VARBINARY:
  2170.         case java.sql.Types.LONGVARBINARY:
  2171.             return true;
  2172.         default:
  2173.             return false;
  2174.         }
  2175.     /* Dates can be converted to char/binary types. */
  2176.     case java.sql.Types.DATE:
  2177.         switch (toType) {
  2178.         case java.sql.Types.CHAR:
  2179.         case java.sql.Types.VARCHAR:
  2180.         case java.sql.Types.LONGVARCHAR:
  2181.         case java.sql.Types.BINARY:
  2182.         case java.sql.Types.VARBINARY:
  2183.         case java.sql.Types.LONGVARBINARY:
  2184.             return true;
  2185.         default:
  2186.             return false;
  2187.         }
  2188.     /* Time can be converted to char/binary types */
  2189.     case java.sql.Types.TIME:
  2190.         switch (toType) {
  2191.         case java.sql.Types.CHAR:
  2192.         case java.sql.Types.VARCHAR:
  2193.         case java.sql.Types.LONGVARCHAR:
  2194.         case java.sql.Types.BINARY:
  2195.         case java.sql.Types.VARBINARY:
  2196.         case java.sql.Types.LONGVARBINARY:
  2197.             return true;
  2198.         default:
  2199.             return false;
  2200.         }
  2201.     /* Timestamp can be converted to char/binary types
  2202.      * and date/time types (with loss of precision).
  2203.      */
  2204.     case java.sql.Types.TIMESTAMP:
  2205.         switch (toType) {
  2206.         case java.sql.Types.CHAR:
  2207.         case java.sql.Types.VARCHAR:
  2208.         case java.sql.Types.LONGVARCHAR:
  2209.         case java.sql.Types.BINARY:
  2210.         case java.sql.Types.VARBINARY:
  2211.         case java.sql.Types.LONGVARBINARY:
  2212.         case java.sql.Types.TIME:
  2213.         case java.sql.Types.DATE:
  2214.             return true;
  2215.         default:
  2216.             return false;
  2217.         }
  2218.     /* We shouldn't get here! */
  2219.     default:
  2220.         return false; // not sure
  2221.     }
  2222. }
  2223.     /**
  2224.      * Is the ODBC Core SQL grammar supported?
  2225.      *
  2226.      * @return true if so
  2227.      *
  2228.      * @throws java.sql.SQLException DOCUMENT ME!
  2229.      */
  2230.     public boolean supportsCoreSQLGrammar() throws java.sql.SQLException {
  2231.         return true;
  2232.     }
  2233.     /**
  2234.      * Are correlated subqueries supported? A JDBC compliant driver always
  2235.      * returns true.
  2236.      *
  2237.      * @return true if so
  2238.      *
  2239.      * @throws java.sql.SQLException DOCUMENT ME!
  2240.      */
  2241.     public boolean supportsCorrelatedSubqueries() throws java.sql.SQLException {
  2242.         return false;
  2243.     }
  2244.     /**
  2245.      * Are both data definition and data manipulation statements within a
  2246.      * transaction supported?
  2247.      *
  2248.      * @return true if so
  2249.      *
  2250.      * @throws java.sql.SQLException DOCUMENT ME!
  2251.      */
  2252.     public boolean supportsDataDefinitionAndDataManipulationTransactions()
  2253.         throws java.sql.SQLException {
  2254.         return false;
  2255.     }
  2256.     /**
  2257.      * Are only data manipulation statements within a transaction supported?
  2258.      *
  2259.      * @return true if so
  2260.      *
  2261.      * @throws java.sql.SQLException DOCUMENT ME!
  2262.      */
  2263.     public boolean supportsDataManipulationTransactionsOnly()
  2264.         throws java.sql.SQLException {
  2265.         return false;
  2266.     }
  2267.     /**
  2268.      * If table correlation names are supported, are they restricted to be
  2269.      * different from the names of the tables? A JDBC compliant driver always
  2270.      * returns true.
  2271.      *
  2272.      * @return true if so
  2273.      *
  2274.      * @throws java.sql.SQLException DOCUMENT ME!
  2275.      */
  2276.     public boolean supportsDifferentTableCorrelationNames()
  2277.         throws java.sql.SQLException {
  2278.         return true;
  2279.     }
  2280.     /**
  2281.      * Are expressions in "ORDER BY" lists supported?
  2282.      *
  2283.      * @return true if so
  2284.      *
  2285.      * @throws java.sql.SQLException DOCUMENT ME!
  2286.      */
  2287.     public boolean supportsExpressionsInOrderBy() throws java.sql.SQLException {
  2288.         return true;
  2289.     }
  2290.     /**
  2291.      * Is the ODBC Extended SQL grammar supported?
  2292.      *
  2293.      * @return true if so
  2294.      *
  2295.      * @throws java.sql.SQLException DOCUMENT ME!
  2296.      */
  2297.     public boolean supportsExtendedSQLGrammar() throws java.sql.SQLException {
  2298.         return false;
  2299.     }
  2300.     /**
  2301.      * Are full nested outer joins supported?
  2302.      *
  2303.      * @return true if so
  2304.      *
  2305.      * @throws java.sql.SQLException DOCUMENT ME!
  2306.      */
  2307.     public boolean supportsFullOuterJoins() throws java.sql.SQLException {
  2308.         return false;
  2309.     }
  2310.     /**
  2311.      * JDBC 3.0
  2312.      *
  2313.      * @return DOCUMENT ME!
  2314.      */
  2315.     public boolean supportsGetGeneratedKeys() {
  2316.         return true;
  2317.     }
  2318.     /**
  2319.      * Is some form of "GROUP BY" clause supported?
  2320.      *
  2321.      * @return true if so
  2322.      *
  2323.      * @throws java.sql.SQLException DOCUMENT ME!
  2324.      */
  2325.     public boolean supportsGroupBy() throws java.sql.SQLException {
  2326.         return true;
  2327.     }
  2328.     /**
  2329.      * Can a "GROUP BY" clause add columns not in the SELECT provided it
  2330.      * specifies all the columns in the SELECT?
  2331.      *
  2332.      * @return true if so
  2333.      *
  2334.      * @throws java.sql.SQLException DOCUMENT ME!
  2335.      */
  2336.     public boolean supportsGroupByBeyondSelect() throws java.sql.SQLException {
  2337.         return true;
  2338.     }
  2339.     /**
  2340.      * Can a "GROUP BY" clause use columns not in the SELECT?
  2341.      *
  2342.      * @return true if so
  2343.      *
  2344.      * @throws java.sql.SQLException DOCUMENT ME!
  2345.      */
  2346.     public boolean supportsGroupByUnrelated() throws java.sql.SQLException {
  2347.         return false;
  2348.     }
  2349.     /**
  2350.      * Is the SQL Integrity Enhancement Facility supported?
  2351.      *
  2352.      * @return true if so
  2353.      *
  2354.      * @throws java.sql.SQLException DOCUMENT ME!
  2355.      */
  2356.     public boolean supportsIntegrityEnhancementFacility()
  2357.         throws java.sql.SQLException {
  2358.         return false;
  2359.     }
  2360.     /**
  2361.      * Is the escape character in "LIKE" clauses supported? A JDBC compliant
  2362.      * driver always returns true.
  2363.      *
  2364.      * @return true if so
  2365.      *
  2366.      * @throws java.sql.SQLException DOCUMENT ME!
  2367.      */
  2368.     public boolean supportsLikeEscapeClause() throws java.sql.SQLException {
  2369.         return true;
  2370.     }
  2371.     /**
  2372.      * Is there limited support for outer joins?  (This will be true if
  2373.      * supportFullOuterJoins is true.)
  2374.      *
  2375.      * @return true if so
  2376.      *
  2377.      * @throws java.sql.SQLException DOCUMENT ME!
  2378.      */
  2379.     public boolean supportsLimitedOuterJoins() throws java.sql.SQLException {
  2380.         return true;
  2381.     }
  2382.     /**
  2383.      * Is the ODBC Minimum SQL grammar supported? All JDBC compliant drivers
  2384.      * must return true.
  2385.      *
  2386.      * @return true if so
  2387.      *
  2388.      * @throws java.sql.SQLException DOCUMENT ME!
  2389.      */
  2390.     public boolean supportsMinimumSQLGrammar() throws java.sql.SQLException {
  2391.         return true;
  2392.     }
  2393.     /**
  2394.      * Does the database support mixed case unquoted SQL identifiers?
  2395.      *
  2396.      * @return true if so
  2397.      *
  2398.      * @throws java.sql.SQLException DOCUMENT ME!
  2399.      */
  2400.     public boolean supportsMixedCaseIdentifiers() throws java.sql.SQLException {
  2401.         return false;
  2402.     }
  2403.     /**
  2404.      * Does the database support mixed case quoted SQL identifiers? A JDBC
  2405.      * compliant driver will always return true.
  2406.      *
  2407.      * @return true if so
  2408.      *
  2409.      * @throws java.sql.SQLException DOCUMENT ME!
  2410.      */
  2411.     public boolean supportsMixedCaseQuotedIdentifiers()
  2412.         throws java.sql.SQLException {
  2413.         return false;
  2414.     }
  2415.     /**
  2416.      * @see DatabaseMetaData#supportsMultipleOpenResults()
  2417.      */
  2418.     public boolean supportsMultipleOpenResults() throws SQLException {
  2419.         return false;
  2420.     }
  2421.     /**
  2422.      * Are multiple ResultSets from a single execute supported?
  2423.      *
  2424.      * @return true if so
  2425.      *
  2426.      * @throws java.sql.SQLException DOCUMENT ME!
  2427.      */
  2428.     public boolean supportsMultipleResultSets() throws java.sql.SQLException {
  2429.         return false;
  2430.     }
  2431.     /**
  2432.      * Can we have multiple transactions open at once (on different
  2433.      * connections)?
  2434.      *
  2435.      * @return true if so
  2436.      *
  2437.      * @throws java.sql.SQLException DOCUMENT ME!
  2438.      */
  2439.     public boolean supportsMultipleTransactions() throws java.sql.SQLException {
  2440.         return true;
  2441.     }
  2442.     /**
  2443.      * @see DatabaseMetaData#supportsNamedParameters()
  2444.      */
  2445.     public boolean supportsNamedParameters() throws SQLException {
  2446.         return false;
  2447.     }
  2448.     /**
  2449.      * Can columns be defined as non-nullable? A JDBC compliant driver always
  2450.      * returns true.
  2451.      *
  2452.      * @return true if so
  2453.      *
  2454.      * @throws java.sql.SQLException DOCUMENT ME!
  2455.      */
  2456.     public boolean supportsNonNullableColumns() throws java.sql.SQLException {
  2457.         return true;
  2458.     }
  2459.     /**
  2460.      * Can cursors remain open across commits?
  2461.      *
  2462.      * @return true if so
  2463.      *
  2464.      * @throws java.sql.SQLException if a database access error occurs
  2465.      *
  2466.      * @see Connection#disableAutoClose
  2467.      */
  2468.     public boolean supportsOpenCursorsAcrossCommit()
  2469.         throws java.sql.SQLException {
  2470.         return false;
  2471.     }
  2472.     /**
  2473.      * Can cursors remain open across rollbacks?
  2474.      *
  2475.      * @return true if so
  2476.      *
  2477.      * @throws java.sql.SQLException if an error occurs
  2478.      *
  2479.      * @see Connection#disableAutoClose
  2480.      */
  2481.     public boolean supportsOpenCursorsAcrossRollback()
  2482.         throws java.sql.SQLException {
  2483.         return false;
  2484.     }
  2485.     /**
  2486.      * Can statements remain open across commits?
  2487.      *
  2488.      * @return true if so
  2489.      *
  2490.      * @throws java.sql.SQLException if an error occurs
  2491.      *
  2492.      * @see Connection#disableAutoClose
  2493.      */
  2494.     public boolean supportsOpenStatementsAcrossCommit()
  2495.         throws java.sql.SQLException {
  2496.         return false;
  2497.     }
  2498.     /**
  2499.      * Can statements remain open across rollbacks?
  2500.      *
  2501.      * @return true if so
  2502.      *
  2503.      * @throws java.sql.SQLException if an error occurs
  2504.      *
  2505.      * @see Connection#disableAutoClose
  2506.      */
  2507.     public boolean supportsOpenStatementsAcrossRollback()
  2508.         throws java.sql.SQLException {
  2509.         return false;
  2510.     }
  2511.     /**
  2512.      * Can an "ORDER BY" clause use columns not in the SELECT?
  2513.      *
  2514.      * @return true if so
  2515.      *
  2516.      * @throws java.sql.SQLException DOCUMENT ME!
  2517.      */
  2518.     public boolean supportsOrderByUnrelated() throws java.sql.SQLException {
  2519.         return false;
  2520.     }
  2521.     /**
  2522.      * Is some form of outer join supported?
  2523.      *
  2524.      * @return true if so
  2525.      *
  2526.      * @throws java.sql.SQLException DOCUMENT ME!
  2527.      */
  2528.     public boolean supportsOuterJoins() throws java.sql.SQLException {
  2529.         return true;
  2530.     }
  2531.     /**
  2532.      * Is positioned DELETE supported?
  2533.      *
  2534.      * @return true if so
  2535.      *
  2536.      * @throws java.sql.SQLException DOCUMENT ME!
  2537.      */
  2538.     public boolean supportsPositionedDelete() throws java.sql.SQLException {
  2539.         return false;
  2540.     }
  2541.     /**
  2542.      * Is positioned UPDATE supported?
  2543.      *
  2544.      * @return true if so
  2545.      *
  2546.      * @throws java.sql.SQLException DOCUMENT ME!
  2547.      */
  2548.     public boolean supportsPositionedUpdate() throws java.sql.SQLException {
  2549.         return false;
  2550.     }
  2551.     /**
  2552.      * JDBC 2.0 Does the database support the concurrency type in combination
  2553.      * with the given result set type?
  2554.      *
  2555.      * @param type defined in java.sql.ResultSet
  2556.      * @param concurrency type defined in java.sql.ResultSet
  2557.      *
  2558.      * @return true if so
  2559.      *
  2560.      * @exception SQLException if a database-access error occurs.
  2561.      *
  2562.      * @see Connection
  2563.      */
  2564.     public boolean supportsResultSetConcurrency(int type, int concurrency)
  2565.         throws SQLException {
  2566.         return ((type == ResultSet.TYPE_SCROLL_INSENSITIVE)
  2567.         && ((concurrency == ResultSet.CONCUR_READ_ONLY)
  2568.         || (concurrency == ResultSet.CONCUR_UPDATABLE)));
  2569.     }
  2570.     /**
  2571.      * @see DatabaseMetaData#supportsResultSetHoldability(int)
  2572.      */
  2573.     public boolean supportsResultSetHoldability(int holdability)
  2574.         throws SQLException {
  2575.         return (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT);
  2576.     }
  2577.     /**
  2578.      * JDBC 2.0 Does the database support the given result set type?
  2579.      *
  2580.      * @param type defined in java.sql.ResultSet
  2581.      *
  2582.      * @return true if so
  2583.      *
  2584.      * @exception SQLException if a database-access error occurs.
  2585.      *
  2586.      * @see Connection
  2587.      */
  2588.     public boolean supportsResultSetType(int type) throws SQLException {
  2589.         return (type == ResultSet.TYPE_SCROLL_INSENSITIVE);
  2590.     }
  2591.     /**
  2592.      * @see DatabaseMetaData#supportsSavepoints()
  2593.      */
  2594.     public boolean supportsSavepoints() throws SQLException {
  2595.         return false;
  2596.     }
  2597.     /**
  2598.      * Can a schema name be used in a data manipulation statement?
  2599.      *
  2600.      * @return true if so
  2601.      *
  2602.      * @throws java.sql.SQLException DOCUMENT ME!
  2603.      */
  2604.     public boolean supportsSchemasInDataManipulation()
  2605.         throws java.sql.SQLException {
  2606.         return false;
  2607.     }
  2608.     /**
  2609.      * Can a schema name be used in an index definition statement?
  2610.      *
  2611.      * @return true if so
  2612.      *
  2613.      * @throws java.sql.SQLException DOCUMENT ME!
  2614.      */
  2615.     public boolean supportsSchemasInIndexDefinitions()
  2616.         throws java.sql.SQLException {
  2617.         return false;
  2618.     }
  2619.     /**
  2620.      * Can a schema name be used in a privilege definition statement?
  2621.      *
  2622.      * @return true if so
  2623.      *
  2624.      * @throws java.sql.SQLException DOCUMENT ME!
  2625.      */
  2626.     public boolean supportsSchemasInPrivilegeDefinitions()
  2627.         throws java.sql.SQLException {
  2628.         return false;
  2629.     }
  2630.     /**
  2631.      * Can a schema name be used in a procedure call statement?
  2632.      *
  2633.      * @return true if so
  2634.      *
  2635.      * @throws java.sql.SQLException DOCUMENT ME!
  2636.      */
  2637.     public boolean supportsSchemasInProcedureCalls()
  2638.         throws java.sql.SQLException {
  2639.         return false;
  2640.     }
  2641.     /**
  2642.      * Can a schema name be used in a table definition statement?
  2643.      *
  2644.      * @return true if so
  2645.      *
  2646.      * @throws java.sql.SQLException DOCUMENT ME!
  2647.      */
  2648.     public boolean supportsSchemasInTableDefinitions()
  2649.         throws java.sql.SQLException {
  2650.         return false;
  2651.     }
  2652.     /**
  2653.      * Is SELECT for UPDATE supported?
  2654.      *
  2655.      * @return true if so
  2656.      *
  2657.      * @throws java.sql.SQLException DOCUMENT ME!
  2658.      */
  2659.     public boolean supportsSelectForUpdate() throws java.sql.SQLException {
  2660.         return false;
  2661.     }
  2662.     /**
  2663.      * @see DatabaseMetaData#supportsStatementPooling()
  2664.      */
  2665.     public boolean supportsStatementPooling() throws SQLException {
  2666.         return false;
  2667.     }
  2668.     /**
  2669.      * Are stored procedure calls using the stored procedure escape syntax
  2670.      * supported?
  2671.      *
  2672.      * @return true if so
  2673.      *
  2674.      * @throws java.sql.SQLException DOCUMENT ME!
  2675.      */
  2676.     public boolean supportsStoredProcedures() throws java.sql.SQLException {
  2677.         return false;
  2678.     }
  2679.     /**
  2680.      * Are subqueries in comparison expressions supported? A JDBC compliant
  2681.      * driver always returns true.
  2682.      *
  2683.      * @return true if so
  2684.      *
  2685.      * @throws java.sql.SQLException DOCUMENT ME!
  2686.      */
  2687.     public boolean supportsSubqueriesInComparisons()
  2688.         throws java.sql.SQLException {
  2689.         return this.conn.getIO().versionMeetsMinimum(4, 1, 0);
  2690.     }
  2691.     /**
  2692.      * Are subqueries in exists expressions supported? A JDBC compliant driver
  2693.      * always returns true.
  2694.      *
  2695.      * @return true if so
  2696.      *
  2697.      * @throws java.sql.SQLException DOCUMENT ME!
  2698.      */
  2699.     public boolean supportsSubqueriesInExists() throws java.sql.SQLException {
  2700.         return this.conn.getIO().versionMeetsMinimum(4, 1, 0);
  2701.     }
  2702.     /**
  2703.      * Are subqueries in "in" statements supported? A JDBC compliant driver
  2704.      * always returns true.
  2705.      *
  2706.      * @return true if so
  2707.      *
  2708.      * @throws java.sql.SQLException DOCUMENT ME!
  2709.      */
  2710.     public boolean supportsSubqueriesInIns() throws java.sql.SQLException {
  2711.         return this.conn.getIO().versionMeetsMinimum(4, 1, 0);
  2712.     }
  2713.     /**
  2714.      * Are subqueries in quantified expressions supported? A JDBC compliant
  2715.      * driver always returns true.
  2716.      *
  2717.      * @return true if so
  2718.      *
  2719.      * @throws java.sql.SQLException DOCUMENT ME!
  2720.      */
  2721.     public boolean supportsSubqueriesInQuantifieds()
  2722.         throws java.sql.SQLException {
  2723.         return this.conn.getIO().versionMeetsMinimum(4, 1, 0);
  2724.     }
  2725.     /**
  2726.      * Are table correlation names supported? A JDBC compliant driver always
  2727.      * returns true.
  2728.      *
  2729.      * @return true if so
  2730.      *
  2731.      * @throws java.sql.SQLException DOCUMENT ME!
  2732.      */
  2733.     public boolean supportsTableCorrelationNames() throws java.sql.SQLException {
  2734.         return true;
  2735.     }
  2736.     /**
  2737.      * Does the database support the given transaction isolation level?
  2738.      *
  2739.      * @param level the values are defined in java.sql.Connection
  2740.      *
  2741.      * @return true if so
  2742.      *
  2743.      * @throws java.sql.SQLException if a database access error occurs
  2744.      *
  2745.      * @see Connection
  2746.      */
  2747.     public boolean supportsTransactionIsolationLevel(int level)
  2748.         throws java.sql.SQLException {
  2749.         if (this.conn.supportsIsolationLevel()) {
  2750.             switch (level) {
  2751.             case java.sql.Connection.TRANSACTION_READ_COMMITTED:
  2752.             case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
  2753.             case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
  2754.             case java.sql.Connection.TRANSACTION_SERIALIZABLE:
  2755.                 return true;
  2756.             default:
  2757.                 return false;
  2758.             }
  2759.         } else {
  2760.             return false;
  2761.         }
  2762.     }
  2763.     /**
  2764.      * Are transactions supported? If not, commit is a noop and the isolation
  2765.      * level is TRANSACTION_NONE.
  2766.      *
  2767.      * @return true if transactions are supported
  2768.      *
  2769.      * @throws java.sql.SQLException DOCUMENT ME!
  2770.      */
  2771.     public boolean supportsTransactions() throws java.sql.SQLException {
  2772.         return this.conn.supportsTransactions();
  2773.     }
  2774.     /**
  2775.      * Is SQL UNION supported? A JDBC compliant driver always returns true.
  2776.      *
  2777.      * @return true if so
  2778.      *
  2779.      * @throws java.sql.SQLException DOCUMENT ME!
  2780.      */
  2781.     public boolean supportsUnion() throws java.sql.SQLException {
  2782.         return this.conn.getIO().versionMeetsMinimum(4, 0, 0);
  2783.     }
  2784.     /**
  2785.      * Is SQL UNION ALL supported? A JDBC compliant driver always returns true.
  2786.      *
  2787.      * @return true if so
  2788.      *
  2789.      * @throws java.sql.SQLException DOCUMENT ME!
  2790.      */
  2791.     public boolean supportsUnionAll() throws java.sql.SQLException {
  2792.         return this.conn.getIO().versionMeetsMinimum(4, 0, 0);
  2793.     }
  2794.     /**
  2795.      * JDBC 2.0 Determine whether or not a visible row update can be detected
  2796.      * by  calling ResultSet.rowUpdated().
  2797.      *
  2798.      * @param type set type, i.e. ResultSet.TYPE_XXX
  2799.      *
  2800.      * @return true if changes are detected by the resultset type
  2801.      *
  2802.      * @exception SQLException if a database-access error occurs.
  2803.      */
  2804.     public boolean updatesAreDetected(int type) throws SQLException {
  2805.         return false;
  2806.     }
  2807.     /**
  2808.      * Does the database use a file for each table?
  2809.      *
  2810.      * @return true if the database uses a local file for each table
  2811.      *
  2812.      * @throws java.sql.SQLException DOCUMENT ME!
  2813.      */
  2814.     public boolean usesLocalFilePerTable() throws java.sql.SQLException {
  2815.         return false;
  2816.     }
  2817.     /**
  2818.      * Does the database store tables in a local file?
  2819.      *
  2820.      * @return true if so
  2821.      *
  2822.      * @throws java.sql.SQLException DOCUMENT ME!
  2823.      */
  2824.     public boolean usesLocalFiles() throws java.sql.SQLException {
  2825.         return false;
  2826.     }
  2827.     /**
  2828.      * Parses the cascade option string and returns the DBMD constant that
  2829.      * represents it (for deletes)
  2830.      *
  2831.      * @param cascadeOptions the comment from 'SHOW TABLE STATUS'
  2832.      *
  2833.      * @return the DBMD constant that represents the cascade option
  2834.      */
  2835.     private int getCascadeDeleteOption(String cascadeOptions) {
  2836.         int onDeletePos = cascadeOptions.indexOf("ON DELETE");
  2837.         if (onDeletePos != -1) {
  2838.             String deleteOptions = cascadeOptions.substring(onDeletePos,
  2839.                     cascadeOptions.length());
  2840.             if (deleteOptions.startsWith("ON DELETE CASCADE")) {
  2841.                 return DatabaseMetaData.importedKeyCascade;
  2842.             } else if (deleteOptions.startsWith("ON DELETE SET NULL")) {
  2843.                 return DatabaseMetaData.importedKeySetNull;
  2844.             } else if (deleteOptions.startsWith("ON DELETE RESTRICT")) {
  2845.                 return DatabaseMetaData.importedKeyRestrict;
  2846.             } else if (deleteOptions.startsWith("ON DELETE NO ACTION")) {
  2847.                 return DatabaseMetaData.importedKeyNoAction;
  2848.             }
  2849.         }
  2850.         return DatabaseMetaData.importedKeyNoAction;
  2851.     }
  2852.     /**
  2853.      * Parses the cascade option string and returns the DBMD constant that
  2854.      * represents it (for Updates)
  2855.      *
  2856.      * @param cascadeOptions the comment from 'SHOW TABLE STATUS'
  2857.      *
  2858.      * @return the DBMD constant that represents the cascade option
  2859.      */
  2860.     private int getCascadeUpdateOption(String cascadeOptions) {
  2861.         int onUpdatePos = cascadeOptions.indexOf("ON UPDATE");
  2862.         if (onUpdatePos != -1) {
  2863.             String updateOptions = cascadeOptions.substring(onUpdatePos,
  2864.                     cascadeOptions.length());
  2865.             if (updateOptions.startsWith("ON UPDATE CASCADE")) {
  2866.                 return DatabaseMetaData.importedKeyCascade;
  2867.             } else if (updateOptions.startsWith("ON UPDATE SET NULL")) {
  2868.                 return DatabaseMetaData.importedKeySetNull;
  2869.             } else if (updateOptions.startsWith("ON UPDATE RESTRICT")) {
  2870.                 return DatabaseMetaData.importedKeyRestrict;
  2871.             } else if (updateOptions.startsWith("ON UPDATE NO ACTION")) {
  2872.                 return DatabaseMetaData.importedKeyNoAction;
  2873.             }
  2874.         }
  2875.         return DatabaseMetaData.importedKeyNoAction;
  2876.     }
  2877.     /**
  2878.      * Adds to the tuples list the exported keys of exportingTable based on the
  2879.      * keysComment from the 'show table status' sql command. KeysComment is
  2880.      * that part of the comment field that follows the "InnoDB free ...;"
  2881.      * prefix.
  2882.      *
  2883.      * @param catalog the database to use
  2884.      * @param exportingTable the table keys are being exported from
  2885.      * @param keysComment the comment from 'show table status'
  2886.      * @param tuples the rows to add results to
  2887.      * @param fkTableName the foreign key table name
  2888.      *
  2889.      * @throws SQLException if a database access error occurs
  2890.      */
  2891.     private void getExportKeyResults(String catalog, String exportingTable,
  2892.         String keysComment, List tuples, String fkTableName)
  2893.         throws SQLException {
  2894.         getResultsImpl(catalog, exportingTable, keysComment, tuples,
  2895.             fkTableName, true);
  2896.     }
  2897.     /**
  2898.      * Returns the DELETE and UPDATE foreign key actions from the given 'SHOW
  2899.      * TABLE STATUS' string, with the DELETE action being the first item in
  2900.      * the array, and the UPDATE action being the second.
  2901.      *
  2902.      * @param commentString the comment from 'SHOW TABLE STATUS'
  2903.      *
  2904.      * @return int[] [0] = delete action, [1] = update action
  2905.      */
  2906.     private int[] getForeignKeyActions(String commentString) {
  2907.         int[] actions = new int[] {
  2908.                 DatabaseMetaData.importedKeyNoAction,
  2909.                 DatabaseMetaData.importedKeyNoAction
  2910.             };
  2911.         int lastParenIndex = commentString.lastIndexOf(")");
  2912.         if (lastParenIndex != (commentString.length() - 1)) {
  2913.             String cascadeOptions = commentString.substring(lastParenIndex + 1)
  2914.                                                  .trim().toUpperCase();
  2915.             actions[0] = getCascadeDeleteOption(cascadeOptions);
  2916.             actions[1] = getCascadeUpdateOption(cascadeOptions);
  2917.         }
  2918.         return actions;
  2919.     }
  2920.     /**
  2921.      * Populates the tuples list with the imported keys of importingTable based
  2922.      * on the keysComment from the 'show table status' sql command.
  2923.      * KeysComment is that part of the comment field that follows the "InnoDB
  2924.      * free ...;" prefix.
  2925.      *
  2926.      * @param catalog the database to use
  2927.      * @param importingTable the table keys are being imported to
  2928.      * @param keysComment the comment from 'show table status'
  2929.      * @param tuples the rows to add results to
  2930.      *
  2931.      * @throws SQLException if a database access error occurs
  2932.      */
  2933.     private void getImportKeyResults(String catalog, String importingTable,
  2934.         String keysComment, List tuples) throws SQLException {
  2935.         getResultsImpl(catalog, importingTable, keysComment, tuples, null, false);
  2936.     }
  2937.     private void getResultsImpl(String catalog, String table,
  2938.         String keysComment, List tuples, String fkTableName, boolean isExport)
  2939.         throws SQLException {
  2940.         // keys will equal something like this:
  2941.         // (parent_service_id child_service_id) REFER ds/subservices(parent_service_id child_service_id)
  2942.         // parse of the string into three phases:
  2943.         // 1: parse the opening parentheses to determine how many results there will be
  2944.         // 2: read in the schema name/table name
  2945.         // 3: parse the closing parentheses
  2946.         int firstLeftParenIndex = keysComment.indexOf('(');
  2947.         String constraintName = keysComment.substring(0, firstLeftParenIndex)
  2948.                                            .trim();
  2949.         keysComment = keysComment.substring(firstLeftParenIndex,
  2950.                 keysComment.length());
  2951.         StringTokenizer keyTokens = new StringTokenizer(keysComment.trim(),
  2952.                 "()", false);
  2953.         String localColumnNamesString = keyTokens.nextToken();
  2954.         StringTokenizer localColumnNames = new StringTokenizer(localColumnNamesString,
  2955.                 " ,");
  2956.         String referCatalogTableString = keyTokens.nextToken();
  2957.         StringTokenizer referSchemaTable = new StringTokenizer(referCatalogTableString,
  2958.                 " /");
  2959.         String referColumnNamesString = keyTokens.nextToken();
  2960.         StringTokenizer referColumnNames = new StringTokenizer(referColumnNamesString,
  2961.                 " ,");
  2962.         referSchemaTable.nextToken(); //discard the REFER token
  2963.         String referCatalog = referSchemaTable.nextToken();
  2964.         String referTable = referSchemaTable.nextToken();
  2965.         if (isExport && !referTable.equals(table)) {
  2966.             return;
  2967.         }
  2968.         if (localColumnNames.countTokens() != referColumnNames.countTokens()) {
  2969.             throw new SQLException("Error parsing foriegn keys definition",
  2970.                 SQLError.SQL_STATE_GENERAL_ERROR);
  2971.         }
  2972.         int keySeqIndex = 1;
  2973.         byte[] connectionCatalogAsBytes = null;
  2974.         if (catalog == null) {
  2975.             connectionCatalogAsBytes = s2b(this.conn.getCatalog());
  2976.         } else {
  2977.             connectionCatalogAsBytes = s2b(catalog);
  2978.         }
  2979.         while (localColumnNames.hasMoreTokens()) {
  2980.             byte[][] tuple = new byte[14][];
  2981.             String localColumnName = localColumnNames.nextToken();
  2982.             String referColumnName = referColumnNames.nextToken();
  2983.             tuple[FKTABLE_CAT] = connectionCatalogAsBytes;
  2984.             tuple[FKTABLE_SCHEM] = null;
  2985.             tuple[FKTABLE_NAME] = s2b((isExport) ? fkTableName : table);
  2986.             tuple[FKCOLUMN_NAME] = s2b(localColumnName);
  2987.             tuple[PKTABLE_CAT] = s2b(referCatalog);
  2988.             tuple[PKTABLE_SCHEM] = null;
  2989.             tuple[PKTABLE_NAME] = s2b((isExport) ? table : referTable);
  2990.             tuple[PKCOLUMN_NAME] = s2b(referColumnName);
  2991.             tuple[KEY_SEQ] = s2b(Integer.toString(keySeqIndex++));
  2992.             int[] actions = getForeignKeyActions(keysComment);
  2993.             tuple[UPDATE_RULE] = s2b(Integer.toString(actions[1]));
  2994.             tuple[DELETE_RULE] = s2b(Integer.toString(actions[0]));
  2995.             tuple[FK_NAME] = s2b(constraintName);
  2996.             tuple[PK_NAME] = null; //not available from show table status
  2997.             tuple[DEFERRABILITY] = s2b(Integer.toString(
  2998.                         java.sql.DatabaseMetaData.importedKeyNotDeferrable));
  2999.             tuples.add(tuple);
  3000.         }
  3001.     }
  3002.     private String getTableNameWithCase(String table) {
  3003.         String tableNameWithCase = (this.conn.lowerCaseTableNames()
  3004.             ? table.toLowerCase() : table);
  3005.         return tableNameWithCase;
  3006.     }
  3007.     private java.sql.ResultSet buildResultSet(com.mysql.jdbc.Field[] fields,
  3008.         java.util.ArrayList rows) throws SQLException {
  3009.         int fieldsLength = fields.length;
  3010.         for (int i = 0; i < fieldsLength; i++) {
  3011.             fields[i].setConnection(this.conn);
  3012.         }
  3013.         return new com.mysql.jdbc.ResultSet(this.conn.getCatalog(), fields,
  3014.             new RowDataStatic(rows), this.conn);
  3015.     }
  3016.     /**
  3017.      * Converts the given string to bytes, using the connection's character
  3018.      * encoding, or if not available, the JVM default encoding.
  3019.      *
  3020.      * @param s DOCUMENT ME!
  3021.      *
  3022.      * @return DOCUMENT ME!
  3023.      */
  3024.     private byte[] s2b(String s) {
  3025.         if ((this.conn != null) && this.conn.useUnicode()) {
  3026.             try {
  3027.                 String encoding = this.conn.getEncoding();
  3028.                 if (encoding == null) {
  3029.                     return s.getBytes();
  3030.                 } else {
  3031.                     SingleByteCharsetConverter converter = this.conn.getCharsetConverter(encoding);
  3032.                     if (converter != null) {
  3033.                         return converter.toBytes(s);
  3034.                     } else {
  3035.                         return s.getBytes(encoding);
  3036.                     }
  3037.                 }
  3038.             } catch (java.io.UnsupportedEncodingException E) {
  3039.                 return s.getBytes();
  3040.             }
  3041.         } else {
  3042.             return s.getBytes();
  3043.         }
  3044.     }
  3045. }