Skip to main content

diesel_derives/
sql_type.rs

1use proc_macro2::{Span, TokenStream};
2use quote::quote;
3use syn::Result;
4use syn::{DeriveInput, Ident};
5
6use crate::model::Model;
7use crate::util::wrap_in_dummy_mod;
8use diesel_attribute_parser::parsers::PostgresType;
9
10pub fn derive(item: DeriveInput) -> Result<TokenStream> {
11    let model = Model::from_item(&item, true, false)?;
12
13    let struct_name = &item.ident;
14    let generic_count = item.generics.params.len();
15    let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl();
16
17    let sqlite_tokens = sqlite_tokens(&item, &model);
18    let mysql_tokens = mysql_tokens(&item, &model);
19    let mariadb_tokens = mariadb_tokens(&item, &model);
20    let pg_tokens = pg_tokens(&item, &model);
21
22    let is_array = struct_name == "Array" && generic_count == 1;
23
24    let enum_sql_type = if model.enum_type {
25        let mut generics = item.generics.clone();
26        generics.params.push(::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "__DB");
        _s
    })syn::parse_quote!(__DB));
27        generics
28            .params
29            .push(::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "const");
        ::quote::__private::push_ident(&mut _s, "__ANYWAY");
        ::quote::__private::push_colon(&mut _s);
        ::quote::__private::push_ident(&mut _s, "bool");
        _s
    })syn::parse_quote!(const __ANYWAY: bool));
30        generics
31            .make_where_clause()
32            .predicates
33            .push(::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "__DB");
        ::quote::__private::push_colon(&mut _s);
        ::quote::__private::push_ident(&mut _s, "diesel");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "backend");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Backend");
        _s
    })syn::parse_quote!(__DB: diesel::backend::Backend));
34        generics
35            .make_where_clause()
36            .predicates
37            .push(::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "diesel");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "internal");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "derives");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "sql_type");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "EnumTypeMapping");
        ::quote::__private::push_colon(&mut _s);
        ::quote::__private::push_ident(&mut _s, "diesel");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "internal");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "derives");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "sql_type");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "EnumMapping");
        ::quote::__private::push_lt(&mut _s);
        ::quote::__private::push_ident(&mut _s, "__DB");
        ::quote::__private::push_gt(&mut _s);
        _s
    })syn::parse_quote!(diesel::internal::derives::sql_type::EnumTypeMapping: diesel::internal::derives::sql_type::EnumMapping<__DB>));
38        let (impl_generics, _, where_clause) = generics.split_for_impl();
39        Some({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "sql_types");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "EnumSqlType");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__ANYWAY");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__DB");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&struct_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "Strategy");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "internal");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "derives");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "sql_type");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "EnumTypeMapping");
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote::quote! {
40
41            impl #impl_generics diesel::sql_types::EnumSqlType<__ANYWAY, __DB> for #struct_name #ty_generics
42                #where_clause
43            {
44                type Strategy = diesel::internal::derives::sql_type::EnumTypeMapping;
45            }
46        })
47    } else {
48        None
49    };
50
51    Ok(wrap_in_dummy_mod({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "sql_types");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "SqlType");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&struct_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "IsNull");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "sql_types");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "is_nullable");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "NotNull");
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "const");
            ::quote::__private::push_ident(&mut _s, "IS_ARRAY");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_ident(&mut _s, "bool");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&is_array, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "sql_types");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "SingleValue");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&struct_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        ::quote::__private::TokenStream::new());
    ::quote::ToTokens::to_tokens(&enum_sql_type, &mut _s);
    ::quote::ToTokens::to_tokens(&sqlite_tokens, &mut _s);
    ::quote::ToTokens::to_tokens(&mysql_tokens, &mut _s);
    ::quote::ToTokens::to_tokens(&mariadb_tokens, &mut _s);
    ::quote::ToTokens::to_tokens(&pg_tokens, &mut _s);
    _s
}quote! {
52        impl #impl_generics diesel::sql_types::SqlType
53            for #struct_name #ty_generics
54        #where_clause
55        {
56            type IsNull = diesel::sql_types::is_nullable::NotNull;
57
58            const IS_ARRAY: bool = #is_array;
59        }
60
61        impl #impl_generics diesel::sql_types::SingleValue
62            for #struct_name #ty_generics
63        #where_clause
64        {
65        }
66
67        #enum_sql_type
68        #sqlite_tokens
69        #mysql_tokens
70        #mariadb_tokens
71        #pg_tokens
72    }))
73}
74
75fn sqlite_tokens(item: &DeriveInput, model: &Model) -> Option<TokenStream> {
76    model
77        .sqlite_type
78        .as_ref()
79        .map(|sqlite_type| Ident::new(&sqlite_type.name.value(), Span::mixed_site()))
80        .map(|ty| {
81            let struct_name = &item.ident;
82            let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl();
83
84            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "derives");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "sql_type");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "expand_sqlite");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "impl");
            ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "sql_types");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "HasSqlType");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&struct_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "sqlite");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Sqlite");
            ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "fn");
                    ::quote::__private::push_ident(&mut _s, "metadata");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_underscore(&mut _s);
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "mut");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    ::quote::__private::push_rarrow(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "diesel");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "sqlite");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "SqliteType");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "diesel");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "sqlite");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "SqliteType");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::ToTokens::to_tokens(&ty, &mut _s);
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
85                diesel::internal::derives::sql_type::expand_sqlite! {
86                    impl #impl_generics diesel::sql_types::HasSqlType<#struct_name #ty_generics>
87                        for diesel::sqlite::Sqlite
88                        #where_clause
89                    {
90                        fn metadata(_: &mut ()) -> diesel::sqlite::SqliteType {
91                            diesel::sqlite::SqliteType::#ty
92                        }
93                    }}
94            }
95        })
96}
97
98fn mysql_tokens(item: &DeriveInput, model: &Model) -> Option<TokenStream> {
99    model
100        .mysql_type
101        .as_ref()
102        .map(|mysql_type| Ident::new(&mysql_type.name.value(), Span::mixed_site()))
103        .map(|ty| {
104            let struct_name = &item.ident;
105            let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl();
106
107            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "derives");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "sql_type");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "expand_mysql");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "impl");
            ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "sql_types");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "HasSqlType");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&struct_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "mysql");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Mysql");
            ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "fn");
                    ::quote::__private::push_ident(&mut _s, "metadata");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_underscore(&mut _s);
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "mut");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    ::quote::__private::push_rarrow(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "diesel");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mysql");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "MysqlType");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "diesel");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "mysql");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "MysqlType");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::ToTokens::to_tokens(&ty, &mut _s);
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
108                diesel::internal::derives::sql_type::expand_mysql! {
109                    impl #impl_generics diesel::sql_types::HasSqlType<#struct_name #ty_generics>
110                        for diesel::mysql::Mysql
111                        #where_clause
112                    {
113                        fn metadata(_: &mut ()) -> diesel::mysql::MysqlType {
114                            diesel::mysql::MysqlType::#ty
115                        }
116                    }
117                }
118            }
119        })
120}
121
122fn mariadb_tokens(item: &DeriveInput, model: &Model) -> Option<TokenStream> {
123    model
124        .mariadb_type
125        .as_ref()
126        .map(|mariadb_type| Ident::new(&mariadb_type.name.value(), Span::mixed_site()))
127        .map(|ty| {
128            let struct_name = &item.ident;
129            let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl();
130
131            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "derives");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "sql_type");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "expand_mariadb");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "impl");
            ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "sql_types");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "HasSqlType");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&struct_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "mariadb");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Mariadb");
            ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "fn");
                    ::quote::__private::push_ident(&mut _s, "metadata");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_underscore(&mut _s);
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "mut");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    ::quote::__private::push_rarrow(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "diesel");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mariadb");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "MariadbType");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "diesel");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "mariadb");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "MariadbType");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::ToTokens::to_tokens(&ty, &mut _s);
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
132                diesel::internal::derives::sql_type::expand_mariadb! {
133                    impl #impl_generics diesel::sql_types::HasSqlType<#struct_name #ty_generics>
134                        for diesel::mariadb::Mariadb
135                        #where_clause
136                    {
137                        fn metadata(_: &mut ()) -> diesel::mariadb::MariadbType {
138                            diesel::mariadb::MariadbType::#ty
139                        }
140                    }
141                }
142            }
143        })
144}
145
146fn pg_tokens(item: &DeriveInput, model: &Model) -> Option<TokenStream> {
147    model.postgres_type.as_ref().map(|ty| {
148        let struct_name = &item.ident;
149        let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl();
150
151        let metadata_fn = match ty {
152            PostgresType::Fixed(oid, array_oid) => {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::__private::push_ident(&mut _s, "metadata");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_underscore(&mut _s);
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "MetadataLookup");
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "pg");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "PgTypeMetadata");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "pg");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "PgTypeMetadata");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "new");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&oid, &mut _s);
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::ToTokens::to_tokens(&array_oid, &mut _s);
                    _s
                });
            _s
        });
    _s
}quote!(
153                fn metadata(_: &mut Self::MetadataLookup) -> diesel::pg::PgTypeMetadata {
154                    diesel::pg::PgTypeMetadata::new(#oid, #array_oid)
155                }
156            ),
157            PostgresType::Lookup(type_name, Some(type_schema)) => {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::__private::push_ident(&mut _s, "metadata");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "lookup");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "MetadataLookup");
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "pg");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "PgTypeMetadata");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "use");
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "pg");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "PgMetadataLookup");
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "lookup");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "lookup_type");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&type_name, &mut _s);
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Some");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&type_schema, &mut _s);
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote!(
158                fn metadata(lookup: &mut Self::MetadataLookup) -> diesel::pg::PgTypeMetadata {
159                    use diesel::pg::PgMetadataLookup;
160                    lookup.lookup_type(#type_name, Some(#type_schema))
161                }
162            ),
163            PostgresType::Lookup(type_name, None) => {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::__private::push_ident(&mut _s, "metadata");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "lookup");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "MetadataLookup");
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "pg");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "PgTypeMetadata");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "use");
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "pg");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "PgMetadataLookup");
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "lookup");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "lookup_type");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&type_name, &mut _s);
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "None");
                    _s
                });
            _s
        });
    _s
}quote!(
164                fn metadata(lookup: &mut Self::MetadataLookup) -> diesel::pg::PgTypeMetadata {
165                    use diesel::pg::PgMetadataLookup;
166                    lookup.lookup_type(#type_name, None)
167                }
168            ),
169        };
170
171        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "diesel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "derives");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "sql_type");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "expand_pg");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "impl");
            ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "sql_types");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "HasSqlType");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&struct_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::__private::push_ident(&mut _s, "diesel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "pg");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Pg");
            ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&metadata_fn, &mut _s);
                    _s
                });
            _s
        });
    _s
}quote! {
172            diesel::internal::derives::sql_type::expand_pg! {
173                impl #impl_generics diesel::sql_types::HasSqlType<#struct_name #ty_generics>
174                    for diesel::pg::Pg
175                    #where_clause
176                {
177                    #metadata_fn
178                }
179            }
180        }
181    })
182}