Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code generator and MetaImpl return CREATE DEFAULT statement instead of just the default expression #15934

Closed
ingvard opened this issue Dec 11, 2023 · 7 comments

Comments

@ingvard
Copy link

ingvard commented Dec 11, 2023

Expected behavior

The Field class should have the correct default value, which is unknown in my case.

Actual behavior

The MSSQL driver implementation for java.sql.DatabaseMetaData#getColumns returns create default my_default_data_type as 'unknown'; for column number 13 instead of the expected string value: unknown. I'm uncertain if this result aligns with the documented column behavior in the JDBC driver documentation:

<LI><B>COLUMN_DEF</B> String {@code =>} default value for the column, which should be interpreted as a string when the value is enclosed in single quotes (may be {@code null}) for default types

However, it appears to be a result of the database engine, causing issues with jOOQ parsing at this point. Consequently, there are numerous logs and an incorrect default value like:

org.jooq.impl.ParserException: Unexpected content after the end of field input: [1:8] create [*]default my_default_data_type as 'unknown'
	at org.jooq.impl.DefaultParseContext.exception(ParserImpl.java:14720)
	at org.jooq.impl.DefaultParseContext.done(ParserImpl.java:14906)
	at org.jooq.impl.DefaultParseContext.lambda$parseField0$8(ParserImpl.java:1001)
	at org.jooq.impl.DefaultParseContext.wrap(ParserImpl.java:14913)
	at org.jooq.impl.DefaultParseContext.parseField0(ParserImpl.java:1001)
	at org.jooq.impl.ParserImpl.parseField(ParserImpl.java:844)
	at org.jooq.impl.ParserImpl.parseField(ParserImpl.java:839)
	at org.jooq.impl.MetaImpl$MetaTable.initColumns(MetaImpl.java:1210)
	at org.jooq.impl.MetaImpl$MetaTable.<init>(MetaImpl.java:799)
	at org.jooq.impl.MetaImpl$MetaSchema.lambda$getTables$2(MetaImpl.java:487)
	at org.jooq.impl.Tools.map(Tools.java:2451)
	at org.jooq.impl.MetaImpl$MetaSchema.getTables(MetaImpl.java:458)
	at org.jooq.impl.FilteredMeta$FilteredSchema.getTables(FilteredMeta.java:335)

I suppose we should extend the field parser for this case.

Steps to reproduce the problem

  1. Create schema:
create default my_default_data_type as 'unknown';

create table table_with_default_val (
    problem_column varchar
);

sp_bindefault 'my_default_data_type', 'table_with_default_val.problem_column';
  1. Left a brake point in the line:
    .parseField(defaultValue)
  2. Call dslContext.meta().schemas.tables.
  3. Catch the error in your logs and the breakpoint.

jOOQ Version

jOOQ Professional Edition 3.18.7

Database product and version

mcr.microsoft.com/mssql/server:2017-latest

Java Version

No response

OS Version

No response

JDBC driver name and version (include name if unofficial driver)

mssql-jdbc:12.5.0.jre11-preview (any)

@lukaseder
Copy link
Member

Thanks a lot for your report. I can reproduce this.

@lukaseder
Copy link
Member

It's what the server returns. Try this query:

select object_definition(default_object_id)
from sys.columns
where name = 'problem_column';

It will reproduce the CREATE DEFAULT ... statement. This affects both the code generator and the runtime meta data. Have you tried reporting this to mssql-jdbc as well? It doesn't look like this is what's expected. In either case, jOOQ should probably be able to handle this as well.

@lukaseder
Copy link
Member

Even the INFORMATION_SCHEMA returns this value:

select column_default
from information_schema.columns
where column_name = 'problem_column'

@lukaseder lukaseder changed the title default of Transact-SQL is processed incorrectly. Code generator and MetaImpl return CREATE DEFAULT statement instead of just the default expression Dec 12, 2023
@lukaseder lukaseder removed this from To do in 3.19 Other improvements Dec 12, 2023
@ingvard
Copy link
Author

ingvard commented Dec 12, 2023

Even the INFORMATION_SCHEMA returns this value:

select column_default
from information_schema.columns
where column_name = 'problem_column'

Exactly, I suspect this is because this field may have a function as a default provider, such as getdate(). How to handle this case in Jooq correctly is uncertain to me. But the simple case (that I mentioned above) can be parsed.

@lukaseder
Copy link
Member

Implementing this now. In order to have a shared implementation between code generator and MetaImpl, I'll implement this directly in the parser (which also throws the exception). There will be an undocumented flag to allow for the create default <identifier> as <constant>; syntax within Parser.parseField(), returning only the constant

@lukaseder
Copy link
Member

There's a slight chance users would prefer that no default is reported on such fields as generated DDL from those tables will inline the default. E.g. with:

create default d_15934 as 'd';
create table t_15934 (d varchar(10));
sp_bindefault 'd_15934', 't_15934.d';

And then:

Meta meta =
create().meta()
        .filterCatalogs(c -> c.getName().equals(schema().getCatalog().getName()))
        .filterSchemas(s -> s.getName().equals(schema().getName()))
        .filterTables(x -> x.getName().equals("t_15934"));

String metaDDL = meta.ddl(new DDLExportConfiguration().flags(DDLFlag.TABLE)).toString();
System.out.println(metaDDL);

The result is now this, after the fix:

create table [test].[dbo].[t_15934] (
  [d] varchar(10) default 'd'
);

That's not exactly the same thing as what the original schema mandates. But we don't currently have a way to represent such named defaults in our meta model, so I don't see how this could be fixed without going all in on the feature support (which I don't think is worth prioritising right now):

lukaseder added a commit that referenced this issue Mar 5, 2024
statement instead of just the default expression
lukaseder added a commit that referenced this issue Mar 5, 2024
statement instead of just the default expression
lukaseder added a commit that referenced this issue Mar 5, 2024
statement instead of just the default expression
lukaseder added a commit that referenced this issue Mar 5, 2024
statement instead of just the default expression
3.13 DDL interpretation automation moved this from To do to Done Mar 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment