2323
2424public class LibsqlDatabaseMetaData implements DatabaseMetaData {
2525
26- private static final Pattern INTEGER_TYPE = Pattern .compile (".*(INT|BOOL).*" );
27- private static final Pattern VARCHAR_TYPE = Pattern .compile (".*(CHAR|CLOB|TEXT|BLOB).*" );
28- private static final Pattern FLOAT_TYPE = Pattern .compile (".*(REAL|FLOA|DOUB|DEC|NUM).*" );
2926 private static final Pattern NAMED_PRIMARY_KEY = Pattern .compile (
3027 "\\ bCONSTRAINT\\ s*(\" [^\" ]+\" |`[^`]+`|\\ [[^\\ ]]+\\ ]|'[^']+'|[^\\ s]+)\\ s*PRIMARY\\ s+KEY\\ b" ,
3128 Pattern .CASE_INSENSITIVE | Pattern .DOTALL );
3229 private static final Pattern NAMED_FOREIGN_KEY = Pattern .compile (
3330 "\\ bCONSTRAINT\\ s+(\" [^\" ]+\" |`[^`]+`|\\ [[^\\ ]]+\\ ]|'[^']+'|[^\\ s]+)\\ s+FOREIGN\\ s+KEY\\ b" ,
3431 Pattern .CASE_INSENSITIVE | Pattern .DOTALL );
35- private static final int UNKNOWN_COLUMN_SIZE = 2_000_000_000 ;
36- private static final int DEFAULT_DECIMAL_DIGITS = 10 ;
3732
3833 private static final List <Col > FOREIGN_KEY_COLUMNS = List .of (
3934 new Col ("PKTABLE_CAT" , "TEXT" ),
@@ -51,6 +46,32 @@ public class LibsqlDatabaseMetaData implements DatabaseMetaData {
5146 new Col ("PK_NAME" , "TEXT" ),
5247 new Col ("DEFERRABILITY" , "INTEGER" ));
5348
49+ private static final List <Col > COLUMN_COLUMNS = List .of (
50+ new Col ("TABLE_CAT" , "TEXT" ),
51+ new Col ("TABLE_SCHEM" , "TEXT" ),
52+ new Col ("TABLE_NAME" , "TEXT" ),
53+ new Col ("COLUMN_NAME" , "TEXT" ),
54+ new Col ("DATA_TYPE" , "INTEGER" ),
55+ new Col ("TYPE_NAME" , "TEXT" ),
56+ new Col ("COLUMN_SIZE" , "INTEGER" ),
57+ new Col ("BUFFER_LENGTH" , "INTEGER" ),
58+ new Col ("DECIMAL_DIGITS" , "INTEGER" ),
59+ new Col ("NUM_PREC_RADIX" , "INTEGER" ),
60+ new Col ("NULLABLE" , "INTEGER" ),
61+ new Col ("REMARKS" , "TEXT" ),
62+ new Col ("COLUMN_DEF" , "TEXT" ),
63+ new Col ("SQL_DATA_TYPE" , "INTEGER" ),
64+ new Col ("SQL_DATETIME_SUB" , "INTEGER" ),
65+ new Col ("CHAR_OCTET_LENGTH" , "INTEGER" ),
66+ new Col ("ORDINAL_POSITION" , "INTEGER" ),
67+ new Col ("IS_NULLABLE" , "TEXT" ),
68+ new Col ("SCOPE_CATALOG" , "TEXT" ),
69+ new Col ("SCOPE_SCHEMA" , "TEXT" ),
70+ new Col ("SCOPE_TABLE" , "TEXT" ),
71+ new Col ("SOURCE_DATA_TYPE" , "INTEGER" ),
72+ new Col ("IS_AUTOINCREMENT" , "TEXT" ),
73+ new Col ("IS_GENERATEDCOLUMN" , "TEXT" ));
74+
5475 private static final List <Col > PRIMARY_KEY_COLUMNS = List .of (
5576 new Col ("TABLE_CAT" , "TEXT" ),
5677 new Col ("TABLE_SCHEM" , "TEXT" ),
@@ -458,130 +479,8 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
458479 String columnPattern = columnNamePattern == null || columnNamePattern .isEmpty () ? "%" : columnNamePattern ;
459480 // getColumns synthesizes its column labels, so the raw SQL must not drive column-origin
460481 // resolution for the result set.
461- return executeMetadataQuery (MetadataSql .columns (tablePattern , columnPattern ), null , LibsqlDatabaseMetaData ::columnsResult );
462- }
463-
464- private static StmtResult columnsResult (StmtResult raw ) {
465- List <Col > columns = List .of (
466- new Col ("TABLE_CAT" , "TEXT" ),
467- new Col ("TABLE_SCHEM" , "TEXT" ),
468- new Col ("TABLE_NAME" , "TEXT" ),
469- new Col ("COLUMN_NAME" , "TEXT" ),
470- new Col ("DATA_TYPE" , "INTEGER" ),
471- new Col ("TYPE_NAME" , "TEXT" ),
472- new Col ("COLUMN_SIZE" , "INTEGER" ),
473- new Col ("BUFFER_LENGTH" , "INTEGER" ),
474- new Col ("DECIMAL_DIGITS" , "INTEGER" ),
475- new Col ("NUM_PREC_RADIX" , "INTEGER" ),
476- new Col ("NULLABLE" , "INTEGER" ),
477- new Col ("REMARKS" , "TEXT" ),
478- new Col ("COLUMN_DEF" , "TEXT" ),
479- new Col ("SQL_DATA_TYPE" , "INTEGER" ),
480- new Col ("SQL_DATETIME_SUB" , "INTEGER" ),
481- new Col ("CHAR_OCTET_LENGTH" , "INTEGER" ),
482- new Col ("ORDINAL_POSITION" , "INTEGER" ),
483- new Col ("IS_NULLABLE" , "TEXT" ),
484- new Col ("SCOPE_CATALOG" , "TEXT" ),
485- new Col ("SCOPE_SCHEMA" , "TEXT" ),
486- new Col ("SCOPE_TABLE" , "TEXT" ),
487- new Col ("SOURCE_DATA_TYPE" , "INTEGER" ),
488- new Col ("IS_AUTOINCREMENT" , "TEXT" ),
489- new Col ("IS_GENERATEDCOLUMN" , "TEXT" ));
490- List <Row > rows = new ArrayList <>();
491- if (raw != null && raw .rows () != null ) {
492- for (Row row : raw .rows ()) {
493- List <Value > values = row .values ();
494- String tableName = text (values .get (0 ));
495- String createSql = text (values .get (1 ));
496- long cid = integer (values .get (2 ));
497- String columnName = text (values .get (3 ));
498- String declaredType = text (values .get (4 ));
499- boolean notNull = integer (values .get (5 )) != 0 ;
500- String columnDefault = text (values .get (6 ));
501- boolean primaryKey = integer (values .get (7 )) != 0 ;
502- long hidden = integer (values .get (8 ));
503-
504- ColumnShape shape = columnShape (declaredType );
505- boolean autoIncrement = primaryKey
506- && SqlAutoIncrement .isAutoIncrementColumn (createSql , columnName );
507- boolean generated = hidden == 2 || hidden == 3 ;
508-
509- rows .add (new Row (List .of (
510- Value .ofNull (),
511- Value .ofNull (),
512- Value .of (tableName ),
513- Value .of (columnName ),
514- Value .of (shape .jdbcType ()),
515- Value .of (shape .typeName ()),
516- Value .of (shape .columnSize ()),
517- Value .of (UNKNOWN_COLUMN_SIZE ),
518- Value .of (shape .decimalDigits ()),
519- Value .of (10 ),
520- Value .of (notNull ? DatabaseMetaData .columnNoNulls : DatabaseMetaData .columnNullable ),
521- Value .ofNull (),
522- Value .of (columnDefault ),
523- Value .of (0 ),
524- Value .of (0 ),
525- Value .of (UNKNOWN_COLUMN_SIZE ),
526- Value .of (cid + 1 ),
527- Value .of (notNull ? "NO" : "YES" ),
528- Value .ofNull (),
529- Value .ofNull (),
530- Value .ofNull (),
531- Value .ofNull (),
532- Value .of (autoIncrement ? "YES" : "NO" ),
533- Value .of (generated ? "YES" : "NO" ))));
534- }
535- }
536- return new StmtResult (columns , rows , 0 , null );
537- }
538-
539- private static ColumnShape columnShape (String declaredType ) {
540- String typeName = declaredType == null ? "TEXT" : declaredType .toUpperCase (Locale .ENGLISH );
541- int jdbcType ;
542- int decimalDigits = DEFAULT_DECIMAL_DIGITS ;
543- if (INTEGER_TYPE .matcher (typeName ).find ()) {
544- jdbcType = Types .INTEGER ;
545- decimalDigits = 0 ;
546- } else if (VARCHAR_TYPE .matcher (typeName ).find ()) {
547- jdbcType = Types .VARCHAR ;
548- decimalDigits = 0 ;
549- } else if (FLOAT_TYPE .matcher (typeName ).find ()) {
550- jdbcType = Types .FLOAT ;
551- } else {
552- jdbcType = Types .VARCHAR ;
553- }
554-
555- int columnSize = UNKNOWN_COLUMN_SIZE ;
556- int startOfDimension = typeName .indexOf ('(' );
557- if (startOfDimension > 0 ) {
558- int endOfDimension = typeName .indexOf (')' , startOfDimension );
559- if (endOfDimension > 0 ) {
560- int dimensionSeparator = typeName .indexOf (',' , startOfDimension );
561- String integerPart ;
562- String decimalPart ;
563- if (dimensionSeparator > 0 ) {
564- integerPart = typeName .substring (startOfDimension + 1 , dimensionSeparator );
565- decimalPart = typeName .substring (dimensionSeparator + 1 , endOfDimension );
566- } else {
567- integerPart = typeName .substring (startOfDimension + 1 , endOfDimension );
568- decimalPart = null ;
569- }
570- try {
571- int integerValue = Integer .parseUnsignedInt (integerPart .trim ());
572- if (decimalPart != null ) {
573- decimalDigits = Integer .parseUnsignedInt (decimalPart .trim ());
574- columnSize = integerValue + decimalDigits ;
575- } else {
576- decimalDigits = 0 ;
577- columnSize = integerValue ;
578- }
579- } catch (NumberFormatException ignored ) {
580- }
581- }
582- typeName = typeName .substring (0 , startOfDimension ).trim ();
583- }
584- return new ColumnShape (jdbcType , typeName , columnSize , decimalDigits );
482+ return executeMetadataQuery (MetadataSql .columns (tablePattern , columnPattern ), null ,
483+ raw -> ColumnMetadata .columns (raw , COLUMN_COLUMNS ));
585484 }
586485
587486 private static String text (Value value ) {
@@ -825,8 +724,6 @@ private Row toRow() {
825724 }
826725 }
827726
828- private record ColumnShape (int jdbcType , String typeName , int columnSize , int decimalDigits ) {}
829-
830727 @ Override public ResultSet getPrimaryKeys (String catalog , String schema , String table ) throws SQLException {
831728 return executeMetadataQuery (MetadataSql .primaryKeys (table ), null , raw -> primaryKeysResult (raw , table ));
832729 }
0 commit comments