34
42
43:-module(sql_parser, [sql_gripe_level/1,
44 sql_parse/4,
45 strip_sql_comments/2]). 46
122
123
124:-op(95, fx, @). 125:-op(100, fx, #). 127:-op(0, xfx, as). 128:-op(0, xfx, on). 129:-op(0, xfx, or). 130:-op(0, xfx, and). 131:-op(0, xfx, not). 132:-op(0, xfx, in). 133:-op(0, xfx, like). 134:-op(100, fx, ??). 135:-op(1200, xfx, --->). 136
137:-use_module(library(chr)). 138:-use_module(library(quintus), [otherwise/0]). 139:-use_module(library(dcg/basics)). 140:-use_module(library(cql/sql_keywords)). 141:-use_module(library(cql/sql_write)). 142:-use_module(library(cql/sql_tokenizer)). 143
144:-use_module(library(cql/cql), [default_schema/1,
145 cql_normalize_name/3,
146 dbms/2,
147 database_attribute/8,
148 domain_database_data_type/2,
149 routine_return_type/3,
150 sql_gripe/3]). 151
152:-chr_option(line_numbers, on). 153:-chr_option(check_guard_bindings, error). 154:-chr_option(debug, off). 155:-chr_option(optimize, full). 156:-chr_option(guard_simplification, off). 157
158:-chr_type 'Table' == any. 159:-chr_type 'Alias' == any. 160:-chr_type 'Type' == any. 161:-chr_type 'Column' == any. 162:-chr_type 'Constraint' == any. 163:-chr_type 'Vars' == any. 164:-chr_type 'N' == any. 165:-chr_type 'QueryId' == any. 166:-chr_type 'Source' == any. 167
168:-chr_constraint type_constraint(-'QueryId', ?'Source', ?'Type', ?'Constraint'). 169:-chr_constraint type_constraint_ready(-'QueryId', ?'Type'). 170:-chr_constraint type_merge_hint(?'Type', ?'Constraint'). 171:-chr_constraint query_table(-'QueryId', ?'Alias', ?'Table'). 172:-chr_constraint derived_query_column(-'QueryId', ?'Alias', ?'Column', ?'Type'). 173:-chr_constraint subquery(-'QueryId', -'QueryId'). 174:-chr_constraint peer_query(-'QueryId', -'QueryId'). 175:-chr_constraint query_is_xml(-'QueryId'). 176:-chr_constraint resolve_types(-'QueryId'). 177:-chr_constraint commit(-'QueryId'). 178:-chr_constraint union_type(-'QueryId', ?'Constraint', ?'Constraint', ?'Constraint'). 179:-chr_constraint derived_table(-'QueryId', +'Table', ?'Constraint'). 180:-chr_constraint find_all_column_types(-'QueryId', ?'Source', ?'Type'). 181:-chr_constraint force_type_not_domain(?'Type'). 182:-chr_constraint frozen_reverse(-'QueryId', ?'Constraint', ?'Constraint'). 183:-chr_constraint cleanup(-'QueryId'). 184
185:-dynamic(cached_gripe_level/1). 186sql_gripe_level(N):-
187 cached_gripe_level(N), !.
188sql_gripe_level(N):-
189 ( getenv('SQL_GRIPE_LEVEL', Atom),
190 atom_number(Atom, N)->
191 true
192 ; otherwise->
193 N = 0 194 ),
195 assert(cached_gripe_level(N)).
196
197
198stream_to_tokens(Stream, Tokens):-
199 stream_to_lazy_list(Stream, List),
200 sql_tokens(Tokens, List, []), !.
201
202
203sql_parse(Head, TrailingComments, Options, Tokens):-
204 Head =.. [Functor, Arg, Types|Args],
205 reverse(Tokens, TR),
206 trailing_comments_reversed(TR, TrailingCommentsReversed, Tail),
207 reverse(Tail, TokensWithoutTrailingComments),
208 reverse(TrailingCommentsReversed, TrailingComments),
209 Goal =.. [Functor, TokensWithoutTrailingComments, [], [query_id(QueryId)|Options], _, 0, _, Arg, T1 |Args],
210 Goal,
211 !,
212 213 214 resolve_types(QueryId),
215 map_nulls_to_ints(T1, Types),
216 consolidate_errors(Arg),
217 cleanup(QueryId),
218 true.
219
220
221map_nulls_to_ints([], []):- !.
222map_nulls_to_ints([merged(A, _, N)|As], [A-native_type(int)|Bs]):-
223 N == {nulltype}, !,
224 map_nulls_to_ints(As, Bs).
225map_nulls_to_ints([merged(A, _, N)|As], [A-native_type(int)|Bs]):-
226 nonvar(N), N = native_type(int(_)), !,
227 map_nulls_to_ints(As, Bs).
228map_nulls_to_ints([merged(A, _, AT)|As], [A-AT|Bs]):-
229 map_nulls_to_ints(As, Bs).
230
([], [], []):- !.
232trailing_comments_reversed([comment(A,B)|In], [comment(A,B)|More], Tail):- !,
233 trailing_comments_reversed(In, More, Tail).
234trailing_comments_reversed(Tail, [], Tail):- !.
235
236term_expansion(OldHead ---> OldBody, NewHead :- NewBody):-
237 OldHead =.. [Functor, A1|Args],
238 NewHead =.. [Functor, In, Out, ContextIn, _, P0, P1, meta(Comments, Source):A1|Args],
239 transform_body(OldBody, In, Out, Source, ContextIn, _, Comments, [], P0, P1, NewBody).
240
241transform_body({A}, In, Out, _, C, C, C1, C2, P0, P0, (A, Out = In, C1 = C2)):- !.
242transform_body(\+(X), In, In, Source, C, C, C1, C1, P0, P0, \+G):-
243 transform_body(X, In, _, Source, C, _, C1, _, P0, _, G).
244transform_body(??(X), In, Out, Source, CIn, COut, C1, C2, P0, P1, Transformed):-
245 transform_body(X, In, Out, Source, CIn, COut, C1, C2, P0, P1, G),
246 functor(X, Functor, Arity),
247 Transformed = (( length(First, 20), append(First, _, In)-> true ; otherwise-> First = In),
248 format(user_error, '----- CALL ~w (~q) ~w~n', [Functor/Arity, G, First]),
249 setup_call_catcher_cleanup(true,
250 G,
251 Reason,
252 ( Reason == ! ->
253 ( length(Last, 20), append(Last, _, Out)-> true ; otherwise-> Last = Out),
254 format(user_error, '----- CUT ~w ~w~n', [Functor/Arity, Last])
255 ; Reason == fail->
256 format(user_error, '----- FAIL ~w~n', [Functor/Arity])
257 ; Reason == exit->
258 ( length(Last, 20), append(Last, _, Out)-> true ; otherwise-> Last = Out),
259 format(user_error, '----- EXIT ~w ~w~n', [Functor/Arity, Last])
260 )),
261 ( var(Reason) ->
262 ( length(Last, 20), append(Last, _, Out)-> true ; otherwise-> Last = Out),
263 format(user_error, '----- PEND ~w ~w~n', [Functor/Arity, Last])
264 ; otherwise->
265 true
266 )
267 ).
268
269transform_body(get_source(Source), In, In, Source, C, C, C1, C1, P0, P0, true):- !.
270transform_body(get_parameter(P0), In, In, _, C, C, C1, C1, P0, P1, P1 is P0 + 1):- !.
271transform_body(!, InOut, InOut, _, C, C, C1, C2, P0, P0, (!, C1 = C2)):- !.
272transform_body(@Functor, In, Out, Source, C, C, C1, C2, P0, P0, get_token(Token, C, C1, C2, In, Out)):- Functor =.. [Token, Source], !.
273transform_body(@Token, In, Out, _, C, C, C1, C2, P0, P0, get_token(Token, C, C1, C2, In, Out)):- !.
274transform_body(#Identifier : Type, In, Out, _, C, C, C1, C2, P0, P0, get_identifier(Identifier, Type, C, C1, C2, In, Out)):-!.
275transform_body(#Identifier, In, Out, _, C, C, C1, C2, P0, P0, get_identifier(Identifier, any, C, C1, C2, In, Out)):-!.
276
277transform_body((A | B), In, Out, Source, CIn, COut, C1, C2, P0, P1, (C, COut = COut1, P1 = P1a ; D, COut = COut2, P1 = P1b)):-
278 !,
279 transform_body(A, In, Out, Source, CIn, COut1, C1, C2, P0, P1a, C),
280 transform_body(B, In, Out, Source, CIn, COut2, C1, C2, P0, P1b, D).
281transform_body((A,B), In, Out, Source, CIn, COut, C1, C2, P0, P2, (C,D)):-
282 !,
283 transform_body(A, In, Intermediate, Source, CIn, CInt, C1, C1b, P0, P1, C),
284 transform_body(B, Intermediate, Out, Source, CInt, COut, C1b, C2, P1, P2, D).
285
286transform_body(List, In, Out, Source, CIn, COut, C1, C2, P0, P1Out, (Goals, P1Out = P1 ; In = Out, CIn = COut, C1 = C2, P1Out = P0)):-
287 is_list(List), !,
288 transform_list_body(List, In, Out, Source, CIn, COut, C1, C2, P0, P1, Goals).
289transform_body(Rule, In, Out, _, CIn, CX, C1, C2, P0, P1, ( C1 = C2, NewRule )):-
290 Rule =.. [Functor|Args],
291 NewRule =.. [Functor, In, Out, CIn, COut, P0, P1|Args],
292 ( ( Functor == set_qid ; Functor == add_option)->
293 CX = COut
294 ; otherwise->
295 CX = CIn
296 ).
297transform_list_body([Tail], In, Out, Source, CIn, COut, C1, C2, P0, P1, Goals):-
298 transform_body(Tail, In, Out, Source, CIn, COut, C1, C2, P0, P1, Goals).
299transform_list_body([Head|Tail], In, Out, Source, CIn, COut, C1, C2, P0, P2, (G, G2)):-
300 transform_body(Head, In, Intermediate, Source, CIn, CInt, C1, C1b, P0, P1, G),
301 transform_list_body(Tail, Intermediate, Out, Source, CInt, COut, C1b, C2, P1, P2, G2).
302
303get_token(Token, Options, [comment(A,B)|C1], C2, [comment(A,B)|X], Out):- !,
304 get_token(Token, Options, C1, C2, X, Out).
305get_token(Token, Options, C1, C1, [TopToken|Out], Out):-
306 ( reverse_lex(TopToken, Options, Token)->
307 true
308 ; atom(TopToken),
309 downcase_atom(TopToken, Token)->
310 true
311 ).
312
313get_identifier(Identifier, Type, Options, [comment(A,B)|C1], C2, [comment(A,B)|X], Out):- !,
314 get_identifier(Identifier, Type, Options, C1, C2, X, Out).
315get_identifier(Identifier, Type, Options, C1, C1, [Top|Out], Out):-
316 ( Type == any ->
317 Identifier = Top
318 ; otherwise->
319 Top = literal(Identifier, Type)
320 ),
321 ( atom(Identifier)->
322 downcase_atom(Identifier, IdentifierLC),
323 \+reserved_sql_keyword(IdentifierLC)
324 ; otherwise->
325 true
326 ),
327 \+reverse_lex(Identifier, Options, _).
328
329reverse_lex('*', _Options, asterisk).
330reverse_lex('/', _Options, solidus).
331reverse_lex('+', _Options, plus_sign).
332reverse_lex('-', _Options, minus_sign).
333reverse_lex(',', _Options, comma).
334reverse_lex('.', _Options, period).
335reverse_lex('(', _Options, left_paren).
336reverse_lex(')', _Options, right_paren).
337reverse_lex('{', _Options, left_curly).
338reverse_lex('}', _Options, right_curly).
339reverse_lex('IS', _Options, is_keyword).
340reverse_lex('Is', _Options, is_keyword).
341reverse_lex('iS', _Options, is_keyword).
342reverse_lex('is', _Options, is_keyword).
343reverse_lex('<', _Options, less_than_operator).
344reverse_lex('=', _Options, equals_operator).
345reverse_lex('<>', _Options, not_equals_operator).
346reverse_lex('>', _Options, greater_than_operator).
347reverse_lex('<=', _Options, less_than_or_equals_operator).
348reverse_lex('>=', _Options, greater_than_or_equals_operator).
349reverse_lex('+', Options, concatenation_operator):- dbms([], [], Options, _, _, _, 'Microsoft SQL Server').
350reverse_lex('||', Options, concatenation_operator):- \+dbms([], [], Options, _, _, _, 'Microsoft SQL Server').
351
352
353add_option(L, L, O, [X|O], P, P, X).
354set_qid(L, L, O, O2, P, P, X):-
355 change_qid(O, X, O2).
356
357change_qid([query_id(_)|T], Qid, [query_id(Qid)|T]):- !.
358change_qid([A|T], Qid, [A|T2]):- !, change_qid(T, Qid, T2).
359
360get_option(L, L, O, O, P, P, X):- memberchk(X, O).
361qid(L, L, O, O, P, P, Qid):- memberchk(query_id(Qid), O).
362default_precision_and_scale(L, L, O, O, P0, P0, P, S):-
363 ( dbms(L, L, O, O, P0, P0, 'Microsoft SQL Server')->
364 P = 18,
365 S = 0
366 ; otherwise->
367 throw(default_unknown)
368 ).
369dbms(L, L, Options, Options, P, P, DBMS):-
370 ( memberchk(dbms(X), Options)->
371 DBMS = X
372 ; otherwise->
373 DBMS = 'Microsoft SQL Server'
374 ).
375
376check_order_by_is_in_top_query(L, L, Options, Options, P, P, Source):-
377 ( memberchk(subquery, Options)->
378 true
379 ; \+memberchk(view_name(_), Options)->
380 381 true
382 ; otherwise->
383 semantic_error(Source, order_by(top_level), 1)
384 ).
385
386action(Action, Types)--->
387 query_expression(Action, Types) | delete_statement_searched(Action, Types) | insert_statement(Action, Types) | update_statement_searched(Action, Types).
388delete_statement_searched(delete(TableName, Where), [])--->
389 @delete, @from, !, table_name(TableName), (@where, search_condition(Condition), {Where = where(Condition)} | {Where = {no_where}}).
390insert_statement(insert(TableName, Values), [])--->
391 @insert, @into, !, table_name(TableName), insert_columns_and_source(Values), [dbms('PostgreSQL'), @returning, query_expression(_,_)].
392insert_columns_and_source(Values)--->
393 from_subquery(Values) | from_constructor(Values) | from_default(Values).
394from_default({default_values})---> @default, @values, !.
395from_subquery(insert_source(Source, Override, Target))--->
396 ( ( @left_paren, insert_column_list(Source), @right_paren) | {Source = {default}} ),
397 ( override_clause(Override) | {Override = {no_override}} ),
398 query_expression(Target, _).
399from_constructor(insert_source(Source, Override, Target))--->
400 ( ( @left_paren, insert_column_list(Source), @right_paren) | {Source = {default}} ),
401 ( override_clause(Override) | {Override = {no_override}} ),
402 table_value_constructor(Target, _).
403update_statement_searched(update(TableName, List, From, Condition), [])--->
404 405 @update, table_reference(TableName),
406 qid(Qid), {strip_sql_comments(TableName, Stripped), determine_tables(Qid, Stripped)},
407 @set, set_clause_list(List),
408 ( @from, from_clause_1(F), {strip_sql_comments(F, CleanedFrom), ( determine_tables(Qid, CleanedFrom)-> From = from(F) ; otherwise->throw(failed_tables(CleanedFrom)))}
409 | {From = {no_from}}),
410 ( @where, search_condition(Where), {Condition = where(Where)} | {Condition = {no_where}}).
411set_clause_list([Head|Tail])--->
412 set_clause(Head), (@comma, set_clause_list(Tail) | {Tail = []}).
413set_clause(set(Target, Source))--->
414 update_target(Target), @equals_operator, update_source(Source). 415update_target(Target)---> column_name(Target). 416update_source(Source)---> value_expression(Source, _) | default_specification(Source, _) | null_specification(Source, _). 417insert_column_list(List)---> column_name_list(List).
418override_clause(overriding_user_value)---> @overriding, @user, @value, !.
419override_clause(overriding_system_value)---> @overriding, @system, @value, !.
420
421
422view_definition(view_definition(Name, Columns, Expression, With), Types)---> (@create), @view, table_name(Name),
423 {
424 strip_sql_comments(Name, NameNoComments),
425 ( NameNoComments = table(identifier(schema(_, literal(dbo, identifier)), _))->
426 true
427 ; otherwise->
428 throw(illegal_view_name(no_schema))
429 )},
430 ( @left_paren, view_column_list(Columns), @right_paren | {Columns = {all}}), with_attribute(With), @as, query_expression(Expression, Types).
431table_name(table(Name))---> qualified_name(Name).
432view_column_list(List)---> column_name_list(List).
433query_expression(Term, T)--->
434 qid(Qid),
435 non_join_query_term(LHS, LT),
436 ( @union, (@all, {Term = union_all(LHS, RHS, Corresponding)} | {Term = union(LHS, RHS, Corresponding)}), (corresponding_spec(Corresponding) | {Corresponding = {no_corresponding}}), set_qid(SubQid), query_expression(RHS, RT), {peer_query(Qid, SubQid), union_type(Qid, LT, RT, T)}
437 | @except, (@all, {Term = except_all(LHS, RHS, Corresponding)} | {Term = except(LHS, RHS, Corresponding)}), (corresponding_spec(Corresponding) | {Corresponding = {no_corresponding}}), query_expression(RHS, RT), {union_type(Qid, LT, RT, T)}
438 | {Term = LHS, T = LT}).
439non_join_query_term(Term, T)---> (non_join_query_primary(LHS, LT) | free_joined_table(LHS, LT)),
440 ( @intersect, ( @all, {Term = intersect_all(LHS, RHS, Corresponding)} | {Term = intersect(LHS, RHS, Corresponding)}),
441 ( corresponding_spec(Corresponding) | {Corresponding = {no_corresponding}}), non_join_query_term(RHS, RT), qid(Qid), {union_type(Qid, LT, RT, T)} | {Term = LHS, T = LT}).
442non_join_query_primary(Primary, T)---> (simple_table(Primary, T) | @left_paren, query_expression(Primary, T), @right_paren).
443simple_table(Table, T)---> query_specification(Query, T), {Table = query(Query)} | table_value_constructor(Values, T), {Table = values(Values)} | explicit_table(Explicit), {Table = explicit_table(Explicit), T = {fixme1}}.
444query_specification(select(Q, Selections, Source, Limit, For), QueryType)--->
445 @select, ( set_quantifier(Q) | {Q = {no_quantifier}} ), [ dbms('Microsoft SQL Server'), top_clause(Limit) ],
446 select_list(Selections, Sources, Types), table_expression(Source), [dbms('PostgreSQL'), limit_clause(Limit)], {var(Limit)->Limit = {no_limit} ; true},
447 ( dbms('Microsoft SQL Server'), for_clause(For), get_source(S1), {semantic_error(for_clause, S1, 2)} | {For = {no_for}}),
448 {(strip_sql_comments(Selections, S), merge_types(S, Sources, Types, QueryType)-> true ; throw(failed_to_resolve))}.
449select_list(N, S, T)---> (@asterisk, qid(Qid), get_source(Source), {N = all, find_all_column_types(Qid, Source, T1), frozen_reverse(Qid, T1, T)} | select_list_1(N, S, T)).
450select_list_1([Head|Tail], [Source|Sources], [Type|Types])---> select_sublist(Head, Source, Type), (@comma, select_list_1(Tail, Sources, Types) | {Tail = [], Sources = [], Types = []}).
451select_sublist(S, Source, Type)---> get_source(Source), derived_column(Column, Type), {S = Column} | qualifier(Qualifier), @period, @asterisk, {S = all(Qualifier), Type = {fixme3}}.
452derived_column(derived_column(Column, As), Type)---> (illegal_null_specification(Column, Type) | value_expression(Column, Type)), (as_clause(As) | {As = {no_alias}}). 453as_clause(Name)---> [@as], column_name(Name).
454table_expression(source(From, Where, GroupBy, OrderBy, Having))--->
455 from_clause(From),
456 qid(Qid),
457 {((From = _:from(F))->
458 strip_sql_comments(F, CleanedFrom),
459 ( determine_tables(Qid, CleanedFrom)-> true ; otherwise->throw(failed_tables(CleanedFrom)))
460 ; From = _:{no_from}->
461 true
462 )},
463 ( where_clause(Where) | {Where = {no_where}}),
464 ( group_by_clause(GroupBy) | {GroupBy = {no_groupby}}),
465 466 467
468 469 470 qid(Qid), set_qid(SubqueryId), {subquery(SubqueryId, Qid)},
471 ( order_by_clause(OrderBy), set_qid(Qid), (having_clause(Having) | {Having = {no_having}})
472 | set_qid(Qid), having_clause(Having), ( set_qid(SubqueryId), order_by_clause(OrderBy), get_source(Source), {semantic_error(order(having, order_by), Source, 2)} | {OrderBy = {no_orderby}})
473 | {OrderBy = {no_orderby}, Having = {no_having}}),
474 set_qid(Qid).
475from_clause(from(From))---> @from, from_clause_1(From).
476from_clause({no_from})---> {true}.
477from_clause_1([Head|Tail])---> table_reference(Head), get_source(Source), (@comma, {semantic_error(Source, deprecated('SQL89-style join', 'Explicit JOIN clauses'), 1)}, from_clause_1(Tail) | {Tail = []}).
478
479table_reference(Reference)---> (@left_paren, table_reference(LHS), @right_paren
480 | derived_table(Derivation, T), correlation_specification(Correlation), {LHS = derived_table(Derivation, Correlation, T)}
481 | table_name(Name), (correlation_specification(Correlation) | {Correlation = {no_correlation}}), {LHS = correlated_table(Name, Correlation)}),
482 [ dbms('Microsoft SQL Server'), with_clause(_) ], 483 ( more_join(RHS), {Reference = join(LHS, RHS)} | {Reference = LHS}).
484more_join(X)--->
485 ( cross_join_rhs(LHS), {Reference = cross_join(LHS)}
486 | qualified_join_rhs(Type, LHS, On), {Reference = qualified_join(Type, LHS, On)}),
487 ( more_join(RHS2), {X = join(Reference, RHS2)} | {X = Reference}).
488correlation_specification(correlation(Name, Columns))---> [@as], #NameMC, (@left_paren, derived_column_list(Columns), @right_paren | {Columns = {no_columns}}), {name_from_identifier(NameMC, Name)}.
489derived_column_list(L)--->column_name_list(L).
490derived_table(Table, T)---> table_subquery(Table, T).
491table_subquery(Query, T)---> subquery(Query, T).
492cross_join_rhs(Reference)---> @cross, @join, table_reference(Reference).
493qualified_join_rhs(Type, Reference, Spec)---> ( @natural, {Type = natural(T1)} | {Type = T1} ), ( join_type(T1) | {T1 = join} ), (@join), table_reference(Reference), ( join_specification(Spec) | {Spec = {no_on}} ).
494free_joined_table(Table, {fixme4})---> table_reference(Table).
495join_type(join_type(Type))---> (@inner, {Type = inner} | outer_join_type(T1), {Type = outer(T1)}, [ @outer ] | @union, {Type = union}).
496outer_join_type(T)---> (@left, {T=left} | @right, {T=right} | @full, {T=full}).
497join_specification(Spec)---> ( join_condition(Spec) | named_columns_join(Spec) ).
498join_condition(on(On)) ---> @on, search_condition(On).
499named_columns_join(columns(Columns))---> @using, @left_paren, join_column_list(Columns), @right_paren.
500join_column_list(Columns)---> column_name_list(Columns).
501set_quantifier(Q)---> ( @distinct, {Q = distinct} | @all, {Q = all} ).
502where_clause(where(Where))---> @where, search_condition(Where).
503corresponding_spec(Columns)---> @corresponding, ( @by, @left_paren, corresponding_column_list(Columns), @right_paren | {Columns = {no_columns}} ).
504corresponding_column_list(List)---> column_name_list(List).
505query_primary(Primary, T)---> ( non_join_query_primary(Primary, T) | free_joined_table(Primary, T) ).
506subquery(subquery(Query), T)---> (@left_paren, add_option(subquery), qid(Qid), set_qid(SubqueryId), {subquery(Qid, SubqueryId)}, query_expression(Query, T), @right_paren).
507column_name_list([Head|Tail])---> column_name(Head), (@comma, column_name_list(Tail) | {Tail = []}).
508column_name(Name)---> #Identifier, \+(@left_paren),
509 {( Identifier = literal(Name, identifier)->
510 true
511 ; Identifier = literal(A,B)-> 512 Name = literal(A,B)
513 ; otherwise->
514 downcase_atom(Identifier, Name)
515 )}.
516explicit_table(table(Table)) ---> @(table), table_name(Table).
517qualifier(Qualifier)---> qualified_name(Qualifier).
521value_expression(V, T)---> numeric_value_expression(V, T), \+(@concatenation_operator), \+(@minus_sign), \+(@period) 522 | string_value_expression(V, T), \+(@concatenation_operator), \+(@minus_sign), \+(@period)
523 | datetime_value_expression(V, T)
524 | interval_value_expression(V, T).
525
527
528numeric_value_expression(V, T)--->
529 numeric_value_expression_1(V, T1),
530 qid(Qid),
531 {left_factor_types(Qid, T1, T)}.
532
533numeric_value_expression_1(V, T)--->
534 get_source(LS), term(LHS, LT), qid(Qid),
535 ( ( @plus_sign, {Op = add} | @minus_sign, {Op = subtract} ),
536 get_source(RS),
537 numeric_value_expression_1(RHS, RT),
538 {T = node(LT, LS, Op, RT, RS),
539 540 541 542 543 left_factor_types(Qid, RT, R1),
544 left_factor_types(Qid, LT, L1),
545 most_general_type(Qid, Source, Source, L1, R1, Op, T1),
546 freeze(T1, determine_operation_from_types(T1, L1, R1, Op, LHS, RHS, V))}
547 | {V = LHS, T = LT}
548 ).
549
550
552determine_operation_from_types(Type, LT, RT, Op, LHS, RHS, V):-
553 554 native_type_of_type(LT, LTT),
555 native_type_of_type(RT, RTT),
556 ( Op == add ->
557 ( native_type_of_type(Type, native_type(varchar(_)))->
558 V = concatenate(LHS, RHS)
559 ; native_type_of_type(Type, native_type(nvarchar(_)))->
560 V = concatenate(LHS, RHS)
561 ; LTT = native_type(datetime),
562 RTT = native_type(int(_))->
563 V = add_interval(LHS, RHS)
564 ; RTT = native_type(datetime),
565 LTT = native_type(int(_))->
566 V = add_interval(RHS, LHS)
567 568 569 ; LTT = native_type(datetime),
570 RTT = native_type(decimal(_,_))->
571 V = add_interval(LHS, RHS)
572 ; otherwise->
573 V = add(LHS, RHS)
574 )
575 ; Op == subtract ->
576 ( LTT = native_type(datetime),
577 RTT = native_type(int(_))->
578 V = add_interval(LHS, negative(RHS))
579 ; RTT = native_type(datetime),
580 LTT = native_type(int(_))->
581 V = add_interval(RHS, negative(LHS))
582 583 584 ; LTT = native_type(datetime),
585 RTT = native_type(decimal(_,_))->
586 V = add_interval(LHS, negative(RHS))
587 ; otherwise->
588 V = subtract(LHS, RHS)
589 )
590 ).
591
592
593native_type_of_type(native_type(X), native_type(X)):- !.
594native_type_of_type(domain(D), native_type(X)):-
595 fetch_domain_data_type(D, X).
596
597term(V, T)---> get_source(LS), factor(LHS, LT), ((@asterisk, {V = multiply(LHS, RHS), Op = multiply} | @solidus, {V = divide(LHS, RHS), Op = divide(RT)}), get_source(RS), term(RHS, RT), {T = node(LT, LS, Op, RT, RS)} | {V = LHS, T = LT}).
598factor(V, T)---> ( (@plus_sign, {V = positive(N)} | @minus_sign, dbms(DBMS), {V = negative(N), (DBMS == 'Microsoft SQL Server' -> force_type_not_domain(T) ; true)}) | { V = N} ), numeric_primary(N, T). 599numeric_primary(N, T)---> value_expression_primary(N, T) | numeric_value_function(N, T).
600value_expression_primary(N, T)--->
601 unsigned_value_specification(N, T) | parameter(N, T) | column_reference(N, T) | set_function_specification(N, T) | case_expression(N, T) | @left_paren, value_expression(N, T), @right_paren | cast_specification(N, T) | scalar_subquery(N, T) | routine_invocation(N, T).
602parameter(parameter(N), native_type(int)) ---> @(?), get_parameter(N). 603column_reference(column(Qualifier, Name), Type)---> ( qualifier(Qualifier), @period | {Qualifier = {no_qualifier}} ), column_name(Name), qid(Qid), get_source(Source), {strip_sql_comments(Qualifier, QS), strip_sql_comments(Name, NS), type_constraint(Qid, Source, Type, typeof(QS, NS)), type_constraint_ready(Qid, Type)}.
604scalar_subquery(S, T)---> subquery(S, ST), qid(Qid), get_source(Source), {type_constraint(Qid, Source, T, scalar(ST)), type_constraint_ready(Qid, T)}.
605having_clause(having(Having))---> @having, search_condition(Having).
606group_by_clause(group_by(List))---> @group, @by, grouping_column_reference_list(List).
607grouping_column_reference_list([Head|Tail])---> grouping_column_reference(Head), ( @comma, grouping_column_reference_list(Tail) | {Tail = []} ).
608grouping_column_reference(group_column(Reference, Collate))---> column_reference(Reference, _), ( collate_clause(Collate) | {Collate = {no_collation}} ).
609collate_clause(collate(Name))---> @collate, collation_name(Name).
610collation_name(collation(Name))---> qualified_name(Name).
611qualified_name(identifier(Qualifier, Name))---> ( schema_name(Qualifier), @period | {Qualifier = {no_schema}}), #Identifier, {name_from_identifier(Identifier, Name)}. 612schema_name(schema(Catalog, Schema))---> ( catalog_name(Catalog), @period | {Catalog = {no_catalog}}), #Schema.
613catalog_name(Catalog)---> #Catalog.
614set_function_specification(S, T)---> (@count, @left_paren, @asterisk, @right_paren, {S = count(all), T = native_type(int)} | general_set_function(S, T)).
615set_function_specification(S, T)---> (@count_big, @left_paren, @asterisk, @right_paren, {S = count(all), T = native_type(bigint)} | general_set_function(S, T)).
616
617general_set_function(set_function(S, Q, A), T)---> set_function_type(S), @left_paren, ( set_quantifier(Q) | {Q = {no_quantifier}} ), value_expression(A, AT), @right_paren, qid(Qid), get_source(Source),
618 {S = _:count ->
619 T = native_type(int)
620 ; S = _:sum->
621 type_merge_hint(T, sum),
622 type_constraint(Qid, Source, T, AT),
623 type_constraint_ready(Qid, T)
624 ; S = _:avg->
625 type_merge_hint(T, avg),
626 type_constraint(Qid, Source, T, AT),
627 type_constraint_ready(Qid, T)
628 ; otherwise->
629 T = AT
630 }.
631set_function_type(T)---> @avg, {T = avg} | @max, {T = max} | @min, {T = min} | @sum, {T = sum} | @count, {T = count}.
632search_condition(C, _Types)---> search_condition(C).
633search_condition(C)---> boolean_term(Head), (@or, search_condition(Tail), {C = or(Head, Tail)} | {C = Head}).
634boolean_term(C)---> boolean_factor(Head), (@and, boolean_term(Tail), {C = and(Head, Tail)} | {C = Head}).
635boolean_factor(C)---> ( @not, {C = not(X)} | {C = X} ), boolean_test(X).
636boolean_test(Test)---> boolean_primary(X), ( @is_keyword, ( @not, {Test = isnot(X, T)} | {Test = is(X, T)}), truth_value(T) | {Test = X}).
637truth_value(T)---> (@true, {T = true} | @false, {T = false} | @unknown, {T = unknown}).
638boolean_primary(P)---> @left_paren, search_condition(Search), {P = search(Search)}, @right_paren | predicate(Pr), {P = predicate(Pr)}.
639predicate(Predicate)---> comparison_predicate(Predicate) | between_predicate(Predicate) | in_predicate(Predicate) | like_predicate(Predicate) | null_predicate(Predicate) | quantified_comparison_predicate(Predicate) | exists_predicate(Predicate) | match_predicate(Predicate) | overlaps_predicate(Predicate).
640comparison_predicate(comparison(CompOp, LHS, RHS))---> row_value_constructor(LHS, LT), comp_op(CompOp), row_value_constructor(RHS, RT), {check_types(LT, RT)}.
641row_value_constructor(Row, Types)---> @left_paren, row_value_constructor_list(List, Types), {Row = list(List)}, @right_paren | row_value_constructor_element(Element, Types), {Row = element(Element)} | row_subquery(SubQuery, Types), {Row = query(SubQuery, Types)}.
642row_value_constructor_element(Element, Type)---> value_expression(Element, Type) | null_specification(Element, Type) | default_specification(Element, Type).
643comp_op(Op)---> @equals_operator, {Op = '='}
644 | @not_equals_operator, {Op = '<>'}
645 | @less_than_operator, {Op = '<'}
646 | @greater_than_operator, {Op = '>'}
647 | @less_than_or_equals_operator, {Op = '<='}
648 | @greater_than_or_equals_operator, {Op = '>='}.
649null_specification({null}, T)---> @null, qid(Qid), get_source(Source), {type_constraint(Qid, Source, T, {nulltype}), type_constraint_ready(Qid, T)}.
650illegal_null_specification({null}, T)---> @null, qid(Qid), get_source(Source), {semantic_error(Source, null_value, 1), type_constraint(Qid, Source, T, {nulltype}), type_constraint_ready(Qid, T)}.
651null_predicate(Predicate)---> row_value_constructor(LHS, _), @is_keyword, ( @not, {Predicate = is_not_null(LHS)} | {Predicate = is_null(LHS)} ), @null. 652default_specification({default}, {defaulttype})---> @default.
653row_subquery(S, T)---> subquery(S, T).
654row_value_constructor_list([Head|Tail], [Type|Types])---> row_value_constructor_element(Head, Type), (@comma, row_value_constructor_list(Tail, Types) | {Tail = [], Types = []}) .
655between_predicate(Term)---> row_value_constructor(LHS, TA), ( @not, {Term = not_between(LHS, Min, Max)} | {Term = between(LHS, Min, Max)}), @between, row_value_constructor(Min, TB), @and, row_value_constructor(Max, TC), {check_types(TA, TB), check_types(TA, TC)}.
656exists_predicate(exists(Query))---> @exists, table_subquery(Query, _).
657in_predicate(P) ---> row_value_constructor(Value, T1), ( @not, {P = not_in(Value, List)} | {P = in(Value, List)} ), @in, in_predicate_value(List, T2), {forall(member(T, T2), check_types(T1, T))}.
658in_predicate_value(In, Types)---> @left_paren, in_value_list(List, Types), {In = list(List)}, @right_paren | table_subquery(Query, Types), {In = query(Query)}.
659in_value_list([Head|Tail], [Type|Types])---> value_expression(Head, Type), ( @comma, in_value_list(Tail, Types) | {Tail = [], Types = []} ).
660like_predicate(P)---> match_value(LHS), ( @not, {P = not_like(LHS, Pattern, Escape)} | {P = like(LHS, Pattern, Escape)}), (@like | @ilike), pattern(Pattern), ( @escape, escape_character(Escape) | {Escape = {no_escape}}).
661match_value(P)---> character_value_expression(P, _).
662pattern(P)---> character_value_expression(P, _).
663escape_character(P)---> character_value_expression(P, _).
664character_value_expression(E, T)---> get_source(S1), character_factor(LHS, LT), (@concatenation_operator, get_source(S2), character_value_expression(RHS, RT), qid(Qid), {E = concatenate(LHS, RHS), concatenate_type(Qid, S1, S2, LT, RT, T)} | {E = LHS, T = LT}).
665character_factor(Factor, T)---> character_primary(F, T), ( collate_clause(C), {Factor = collated_factor(F, C)} | {Factor = F} ).
666character_primary(X, T)---> value_expression_primary(X, T) | string_value_function(X, T).
667match_predicate(match(Unique, MatchLevel, LHS, RHS))---> row_value_constructor(LHS, TL), @match, [ @unique, {Unique = unique} ], [ (@partial, {MatchLevel = partial} | @full, {MatchLevel = full}) ], table_subquery(RHS, TR), {check_types(TL, TR)}.
668overlaps_predicate(overlaps(LHS, RHS))---> row_value_constructor(LHS, TL), @overlaps, row_value_constructor(RHS, TR), {check_types(TL, TR)}.
669quantified_comparison_predicate(quantified_comparison(Op, Quantifier, LHS, RHS))---> row_value_constructor(LHS, TL), comp_op(Op), quantifier(Quantifier), table_subquery(RHS, TR), {check_types(TL, TR)}.
670quantifier(Quantifier)---> @all, {Quantifier = all} | @some, {Quantifier = some}.
671table_value_constructor(N, T)---> @values, table_value_constructor_list(N, T).
672table_value_constructor_list([Head|Tail], [Type|Types])---> row_value_constructor(Head, Type), (@comma, table_value_constructor_list(Tail, Types) | {Tail = [], Types = []}).
673case_expression(N, T)---> case_abbreviation(N, T) | case_specification(N, T).
674case_abbreviation(V, T)---> @nullif, @left_paren, value_expression(LHS, LT), @comma, value_expression(RHS, RT), @right_paren, qid(Qid), get_source(Source), {V = nullif(LHS, RHS), most_general_type(Qid, Source, Source, LT, RT, case, T)}
675 | @coalesce, @left_paren, coalesce_list(List, Types, Sources), @right_paren, qid(Qid), {V = coalesce(List), coalesce_type(Qid, Types, Sources, T)}.
676coalesce_list([Head|Tail], [Type|Types], [Source|Sources])---> get_source(Source), (null_specification(Head, Type), get_source(Source), {semantic_error(Source, coalesce(null_argument), 1)} | value_expression(Head, Type)), ( @comma, coalesce_list(Tail, Types, Sources) | {Tail = [], Types = [], Sources = []} ).
677case_specification(N, T)---> searched_case(N, T) | simple_case(N, T).
678simple_case(simple_case(Operand, List, Else), T)---> @case, qid(Qid), case_operand(Operand), simple_when_clause_list(List, Types, Sources), ( get_source(Source), else_clause(Else, ElseType), {coalesce_type(Qid, [ElseType|Types], [Source|Sources], T)} | {Else = {no_else}, coalesce_type(Qid, Types, Sources, T)} ), @end.
679simple_when_clause_list([Head|Tail], [Type|Types], [Source|Sources])---> get_source(Source), simple_when_clause(Head, Type), (simple_when_clause_list(Tail, Types, Sources) | {Tail = [], Types = [], Sources = []}).
680case_operand(X)---> value_expression(X, _).
681simple_when_clause(when(When, Result), T)---> @when, when_operand(When), @then, result(Result, T).
682when_operand(X)---> value_expression(X, _).
683result(X, T)---> null_specification(X, T) | result_expression(X, T).
684result_expression(X, T)---> value_expression(X, T).
685else_clause(else(Else), T)---> @else, result(Else, T).
686searched_case(case(Cases, Else), T)---> @case, qid(Qid), searched_when_clause_list(Cases, Types, Sources), ( get_source(Source), else_clause(Else, ElseT), {coalesce_type(Qid, [ElseT|Types], [Source|Sources], T)} | {Else = {no_else}, force_type_not_domain(T), coalesce_type(Qid, Types, Sources, T)} ), (@end).
687searched_when_clause_list([Head|Tail], [Type|Types], [Source|Sources])---> get_source(Source), searched_when_clause(Head, Type), (searched_when_clause_list(Tail, Types, Sources) | {Tail = [], Types = [], Sources = []}).
688searched_when_clause(when(searched(Search), Result), T)---> @when, search_condition(Search), @then, result(Result, T).
689numeric_value_function(N, native_type(int))---> position_expression(N) | extract_expression(N) | length_expression(N).
690position_expression(position(A, B))---> @position, @left_paren, character_value_expression(A, _), @in, character_value_expression(B, _), @right_paren.
691extract_expression(extract(Field, Source))---> @extract, @left_paren, extract_field(Field), @from, extract_source(Source), @right_paren.
692length_expression(A)---> char_length_expression(A) | octet_length_expression(A) | bit_length_expression(A).
693char_length_expression(char_length(A))---> ( @char_length | @character_length ), @left_paren, string_value_expression(A, _), @right_paren.
694string_value_expression(X, T)---> character_value_expression(X, T) | bit_value_expression(X, T).
695octet_length_expression(octet_length(A))---> @octet_length, @left_paren, string_value_expression(A, _), @right_paren.
696bit_length_expression(bit_length(A))---> @bit_length, @left_paren, string_value_expression(A, _), @right_paren.
697extract_field(Field)---> datetime_field(Field) | time_zone_field(Field).
698extract_source(V)---> datetime_value_expression(V, _) | interval_value_expression(V, _).
699unsigned_value_specification(Value, native_type(int(X)))---> #Value : int(X).
700routine_invocation(routine(Name, Args), Type)---> qualified_name(Name), @left_paren, dbms(DBMS), {not_a_builtin_function(DBMS, Name)}, (sql_argument_list(Args) | {Args = []}), @right_paren, {routine_type(Name, Type)}.
701sql_argument_list([Head|Tail])---> sql_argument(Head), (@comma, sql_argument_list(Tail) | {Tail = []}).
702sql_argument(Arg)---> value_expression(Arg, _).
703cast_specification(cast(Operand, Target), Type)---> @cast, @left_paren, cast_operand(Operand), @as, cast_target(Target), {strip_sql_comments(Target, Type)}, @right_paren.
704cast_operand(Operand)---> @null, {Operand = {null}} | value_expression(Operand, _).
705cast_target(Target)---> data_type(Type), {Target = native_type(Type)} | domain_name(Domain), {Target = domain(Domain)}.
706domain_name(Name)---> qualified_name(Name).
707data_type(Type)---> character_string_type(Type), ( @character, @set, character_set_specification(_) | {true}) | national_character_string_type(Type) | bit_string_type(Type) | numeric_type(Type) | datetime_type(Type) | interval_type(Type).
708character_string_type(varchar(Length))---> @character, ( @left_paren, length(Length), @right_paren | {Length = 30})
709 | @char, ( @left_paren, length(Length), @right_paren | {Length = 30})
710 | @character, @varying, ( @left_paren, length(Length), @right_paren | {Length = 30})
711 | @char, @varying, ( @left_paren, length(Length), @right_paren | {Length = 30})
712 | @varchar, ( @left_paren, length(Length), @right_paren | {Length = 30}).
713length(Length)---> #Length : int(_) | (@max, {Length = max}).
714national_character_string_type(nchar_type(Length))--->
715 @national, @character, [ @left_paren, length(Length), @right_paren ]
716 | @national, @char, [ @left_paren, length(Length), @right_paren ]
717 | @nchar, [ @left_paren, length(Length), @right_paren ]
718 | @national, @character, @varying, [ @left_paren, length(Length), @right_paren ]
719 | @national, @char, @varying, [ @left_paren, length(Length), @right_paren ]
720 | @nchar, @varying, [ @left_paren, length(Length), @right_paren ].
721bit_string_type(bit_type(Length))---> @bit, [ @left_paren, length(Length), @right_paren ] | @bit, @varying, [ @left_paren, length(Length), @right_paren ].
722numeric_type(Type)---> exact_numeric_type(Type) | approximate_numeric_type(Type).
723exact_numeric_type(Type)---> @numeric, {Type = decimal(Precision, Scale)}, ( @left_paren, precision(Precision), ( @comma, scale(Scale) | {Scale = {no_scale}}), @right_paren | default_precision_and_scale(Precision, Scale))
724 | @decimal, {Type = decimal(Precision, Scale)}, ( @left_paren, precision(Precision), ( @comma, scale(Scale) | {Scale = {no_scale}}), @right_paren | default_precision_and_scale(Precision, Scale) )
725 | @dec, {Type = decimal(Precision, Scale)}, ( @left_paren, precision(Precision), ( @comma, scale(Scale) | {Scale = {no_scale}}), @right_paren | default_precision_and_scale(Precision, Scale) )
726 | @integer, {Type = int}
727 | @int, {Type = int}
728 | @smallint, {Type = smallint}
729 | dbms('Microsoft SQL Server'), @tinyint, {Type = tinyint}.
730precision(Precision)---> #Precision : int(_).
731scale(Scale)---> #Scale : int(_).
732approximate_numeric_type(Type)---> @float, ( @left_paren, precision(Precision), @right_paren | {Precision = {no_precision}}), {Type = float(Precision)} | @real, {Type = real} | @double, precision(Precision), {Type = double(Precision)}.
733datetime_value_expression(V, T)---> (datetime_term(LHS, LT) | interval_value_expression(LHS, LT)),
734 ( ( @plus_sign, {V = add(LHS, RHS), Op = add} | @minus_sign, {V = subtract(LHS, RHS), Op = subtract}), datetime_value_expression(RHS, RT), qid(Qid), get_source(Source), {most_general_type(Qid, Source, Source, LT, RT, Op, T)} | {V = LHS, T = LT}).
735order_by_clause(order_by(List))---> @order, @by, get_source(Source), check_order_by_is_in_top_query(Source), sort_specification_list(List).
736sort_specification_list([Head|Tail])---> sort_specification(Head), ( @comma, sort_specification_list(Tail) | {Tail = []}).
737sort_specification(sort_key(Key, Collate, Order))---> sort_key(Key), ( collate_clause(Collate) | {Collate = {no_collation}} ), ( ordering_specification(Order) | {Order = {no_order}} ).
740sort_key(Key)---> value_expression(C, _), {Key = sort_column(C)} | #I : int(_), {Key = index(I)}.
741ordering_specification(S)---> @asc, {S = asc} | @desc, {S = desc}.
742
743interval_term(V, T)---> interval_factor(LHS, LT), (((@asterisk, {V = multiply(LHS, RHS), Op = multiply} | @solidus, {V = divide(LHS, RHS), Op = divide(RT)}), interval_term(RHS, RT), qid(Qid), get_source(Source), {most_general_type(Qid, Source, Source, LT, RT, Op, T)}) | {V = LHS, T = LT})
744 | term(LHS, LT), @asterisk, interval_factor(RHS, RT), qid(Qid), get_source(Source), {T = multiply(LHS, RHS), most_general_type(Qid, Source, Source, LT, RT, multiply, T)}.
745interval_factor(F, T)---> (@plus_sign, {F = positive(F1)} | @minus_sign, {F = negative(F1)} | {F = F1}), interval_primary(F1, T).
746interval_primary(interval(P, Q), T)---> value_expression_primary(P, T), ( interval_qualifier(Q) | {Q = {no_qualifier}} ).
747interval_value_expression(V, T)---> interval_term(LHS, LT), (((@plus_sign, {V = add(LHS, RHS), Op = add} | @minus_sign, {V = subtract(LHS, RHS), Op = subtract}), interval_term(RHS, RT), qid(Qid), get_source(Source), {most_general_type(Qid, Source, Source, LT, RT, Op, T)}) | {V = LHS, T = LT})
748 | @left_paren, datetime_value_expression(LHS, LT), @minus_sign, datetime_term(RHS, RT), @right_paren, interval_qualifier(Q), qid(Qid), get_source(Source), {T = qualified_subtract(Q, LHS, RHS), most_general_type(Qid, Source, Source, LT, RT, subtract, T)}.
749datetime_term(V, T)---> datetime_factor(V, T).
750datetime_factor(V, T)---> datetime_primary(P, T1), ( time_zone(TZ), qid(Qid), get_source(Source), {V = date_with_timezone(P, TZ), most_general_type(Qid, Source, Source, datetime_with_timezone, T1, add, T)} | {V = P, T = T1}).
751datetime_primary(V, T)---> value_expression_primary(V, T) | datetime_value_function(V, T).
752time_zone(T)---> @at, time_zone_specifier(T).
753time_zone_specifier(time_zone(T))---> @local, {T = local} | @time, @zone, interval_value_expression(T, _).
754time_zone_field(T)---> (@timezone_hour, {T = timezone_hour} | @timezone_minute, {T = timezone_minute}).
755
756datetime_type(T)---> @date, {T = date}
757 | @time, ( @left_paren, time_precision(P), @right_paren | {P = {no_precision}}), [ @with, @time, @zone], {T = time(P)}
758 | @timestamp, ( @left_paren, timestamp_precision(P), @right_paren | {P = {no_precision}}), [ @with, @time, @zone], {T = timestamp(P)}.
759time_precision(P)---> precision(P).
760timestamp_precision(P)---> precision(P).
761character_set_specification(P) ---> #P.
762
763
765datetime_field(_)---> {fail}.
766interval_qualifier(_)---> {fail}.
767interval_type(_)---> {fail}.
768string_value_function(_, _)---> {fail}.
769bit_value_expression(_, _)---> {fail}.
770
772:-discontiguous(string_value_function/8). 773string_value_function(ltrim(S), T)---> dbms('Microsoft SQL Server'), @ltrim, @left_paren, value_expression(S, T), @right_paren.
774string_value_function(rtrim(S), T)---> dbms('Microsoft SQL Server'), @rtrim, @left_paren, value_expression(S, T), @right_paren.
775string_value_function(left(S, N), T)---> dbms('Microsoft SQL Server'), @left, @left_paren, value_expression(S, ST), @comma, numeric_value_expression(N, _), @right_paren, get_source(Source), sized_varchar_type(N, Source, ST, T).
776string_value_function(right(S, N), T)---> dbms('Microsoft SQL Server'), @right, @left_paren, value_expression(S, ST), @comma, numeric_value_expression(N, _), @right_paren, get_source(Source), sized_varchar_type(N, Source, ST, T).
777string_value_function(isnull(P, C), T)---> dbms('Microsoft SQL Server'), @isnull(Source), {semantic_error(Source, deprecated(isnull, coalesce), 1)}, @left_paren, value_expression(P, T), @comma, value_expression(C, _), @right_paren. 778string_value_function(replace(S, M, R), T)---> dbms('Microsoft SQL Server'), @replace, @left_paren, string_value_expression(S, ST), @comma, string_value_expression(M, _), @comma, string_value_expression(R, _), @right_paren,
779 get_source(Source),
780 {type_merge_hint(T, max),
781 type_constraint(Qid, Source, T, native_type(varchar(8000))),
782 type_constraint(Qid, Source, T, ST)}.
783
784 string_value_function(upper(S), T)---> dbms('Microsoft SQL Server'), @upper, @left_paren, value_expression(S, T), @right_paren.
785string_value_function(lower(S), T)---> dbms('Microsoft SQL Server'), @lower, @left_paren, value_expression(S, T), @right_paren.
786string_value_function(substring(Source, Start, Length), T)--->
787 dbms('Microsoft SQL Server'), @substring, @left_paren, character_value_expression(Source, ST), @comma, numeric_value_expression(Start, _), @comma, numeric_value_expression(Length, _), @right_paren, get_source(Source), sized_varchar_type(Length, Source, ST, T).
788string_value_function(datename(Type, Source), varchar) ---> dbms('Microsoft SQL Server'), @datename, @left_paren, sql_server_date_part(Type), @comma, datetime_value_expression(Source, _), @right_paren.
789string_value_function(dbname({}), native_type(nvarchar(128)))---> dbms('Microsoft SQL Server'), @db_name, @left_paren, @right_paren.
790string_value_function(permissions(S), varchar)---> dbms('Microsoft SQL Server'), @permissions, @left_paren, character_value_expression(S, _), @right_paren.
791string_value_function(username(String), native_type(nvarchar(128)))---> dbms('Microsoft SQL Server'), @user_name, @left_paren, character_value_expression(String, _), @right_paren.
792string_value_function(str(S), T)---> dbms('Microsoft SQL Server'), @str, @left_paren, qid(Qid), get_source(Source), {type_merge_hint(T, str), type_constraint(Qid, Source, T, native_type(varchar(1))), type_constraint(Qid, Source, T, ST)}, numeric_value_expression(S, ST), @right_paren.
793
794:-discontiguous(datetime_value_function/8). 795datetime_value_function(dateadd(Type, N, Source), native_type(datetime))---> dbms('Microsoft SQL Server'), @dateadd, @left_paren, sql_server_date_part(Type), @comma, numeric_value_expression(N, _), @comma, datetime_value_expression(Source, _), @right_paren.
796
797:-discontiguous(numeric_value_function/8). 798numeric_value_function(current_timestamp, native_type(datetime))---> @current_timestamp.
799numeric_value_function(getdate({}), native_type(datetime))---> dbms('Microsoft SQL Server'), @getdate, @left_paren, @right_paren.
800numeric_value_function(fn_now({}), native_type(datetime))---> dbms('Microsoft SQL Server'), @left_curly, @fn, @now, @left_paren, @right_paren, @right_curly, get_source(Source), {semantic_error(sql_escape, Source, 1)}.
801numeric_value_function(isnull(P, C), T)---> dbms('Microsoft SQL Server'), @isnull(Source), {semantic_error(Source, deprecated(isnull, coalesce), 1)}, @left_paren, value_expression(P, T), @comma, value_expression(C, _), @right_paren.
802numeric_value_function(datediff(Type, LHS, RHS), native_type(int))---> dbms('Microsoft SQL Server'), @datediff, @left_paren, sql_server_date_part(Type), @comma, datetime_value_expression(LHS, _), @comma, numeric_value_expression(RHS, _), @right_paren.
803numeric_value_function(day(S), native_type(int))---> dbms('Microsoft SQL Server'), @day, @left_paren, datetime_value_expression(S, _), @right_paren.
804numeric_value_function(month(S), native_type(int))---> dbms('Microsoft SQL Server'), @month, @left_paren, datetime_value_expression(S, _), @right_paren.
805numeric_value_function(year(S), native_type(int))---> dbms('Microsoft SQL Server'), @year, @left_paren, datetime_value_expression(S, _), @right_paren.
806
807numeric_value_function(datepart(Type, S), native_type(int))---> dbms('Microsoft SQL Server'), @datepart, @left_paren, sql_server_date_part(Type), @comma, datetime_value_expression(S, _), @right_paren.
808numeric_value_function(charindex(Source, Search, Start), native_type(int))---> dbms('Microsoft SQL Server'), @charindex, @left_paren, character_value_expression(Source, _), @comma, string_value_expression(Search, _), ( @comma, numeric_value_expression(Start, _) | {Start = {no_start}}), @right_paren.
809numeric_value_function(len(Source), native_type(int))---> dbms('Microsoft SQL Server'), @len, @left_paren, character_value_expression(Source, _), @right_paren.
810numeric_value_function(abs(S), T)---> dbms('Microsoft SQL Server'), @abs, @left_paren, {force_type_not_domain(T)}, numeric_value_expression(S, T), @right_paren.
811numeric_value_function(round(S, P), T)---> dbms('Microsoft SQL Server'), @round, @left_paren, {force_type_not_domain(T)}, numeric_value_expression(S, T), @comma, numeric_value_expression(P, _), @right_paren.
812numeric_value_function(floor(S), T)---> dbms('Microsoft SQL Server'), @floor, @left_paren, numeric_value_expression(S, ST), @right_paren, qid(Qid), get_source(Source), {type_merge_hint(T, round), type_constraint(Qid, Source, T, ST), type_constraint_ready(Qid, T)}.
813numeric_value_function(ceiling(S), native_type(int))---> dbms('Microsoft SQL Server'), @ceiling, @left_paren, numeric_value_expression(S, _), @right_paren.
814sql_server_date_part(T)---> ( @year | @yy | @yyyy), {T = year}
815 | (@quarter | @qq | @q ), {T = quarter}
816 | (@month | @mm | @m), {T = month}
817 | (@dayofyear | @dy), {T = dayofyear}
818 | (@day | @dd | @d | #literal(day, _), get_source(Source), {semantic_error(superfluous_quote(day), Source, 1)}), {T = day}
819 | (@week | @wk | @ww), {T = week}
820 | (@weekday | @dw | @w), {T = weekday}
821 | (@hour | @hh), {T = hour}
822 | (@minute | @mi | @n), {T = minute}
823 | (@second | @ss | @s), {T = second}
824 | (@millisecond | @ms), {T = millisecond}
825 | (@microsecond | @mcs), {T = microsecond}
826 | (@nanosecond | @ns), {T = nanosecond}.
827
828
829:-discontiguous(cast_specification/8). 830cast_specification(precision_cast(Target, Operand, P), Type)---> dbms('Microsoft SQL Server'), @convert, @left_paren, cast_target(Target), @comma, cast_operand(Operand), ( @comma, precision(P) | {P = {no_precision}} ), @right_paren, {strip_sql_comments(Target, Type)}.
831
832top_clause(top(N))---> @top, numeric_value_expression(NN, _T), ( @percent, get_source(Source), {semantic_error(percent, Source, 1)}, {N = percent(NN)} | {N = NN}). 833limit_clause(top(N))---> @limit, numeric_value_expression(N, _T). 834
835with_attribute(With)---> @with, @schemabinding, {With = with(schemabinding)} 836 | {With = {no_with}}. 837
838with_clause(with(nolock))---> @with, @left_paren, @nolock, @right_paren.
839with_clause(with(noexpand))---> @with, @left_paren, @noexpand, @right_paren. 840
841for_clause(for(xml_path(I)))---> @for, @xml, @path, @left_paren, string_value_expression(I, _), @right_paren, qid(Q), {query_is_xml(Q)}.
842:-discontiguous(grouping_column_reference/7). 843grouping_column_reference(group_expression(Expression, Collate))---> dbms('Microsoft SQL Server'), value_expression(Expression, _), ( collate_clause(Collate) | {Collate = {no_collation}} ).
844:-discontiguous(sort_key/7). 845sort_key(sort_expression(Expression))---> dbms('Microsoft SQL Server'), value_expression(Expression, _).
846
847:-discontiguous(datetime_type/7). 848datetime_type(datetime)---> @datetime.
849
850
851sized_varchar_type(L, L, O, O, P0, P0, Length, Source, SourceT, T):-
852 memberchk(query_id(Qid), O),
853 strip_sql_comments(Length, LS),
854 ( integer(LS) ->
855 856 type_merge_hint(T, sized_varchar),
857 type_constraint(Qid, Source, T, native_type(varchar(LS))),
858 type_constraint(Qid, Source, T, SourceT)
859 ; otherwise->
860 force_type_not_domain(T),
861 type_constraint(Qid, Source, T, SourceT),
862 type_constraint_ready(Qid, T)
863 ).
864
865sql_explain(_).
866user:goal_expansion(sql_explain(_), true).
868
869remove_quoted_column @
870 type_constraint(QueryId, Source, Type, typeof(identifier(A, B), literal(ColumnName, string)))
871 <=>
872 type_constraint(QueryId, Source, Type, typeof(identifier(A, B), ColumnName)).
873
874define_type_from_subquery @
875 derived_query_column(QueryId, TableAlias, Column, DerivedType)
876 \
877 type_constraint(QueryId, Source, Type, typeof(identifier(_, TableAlias), Column))
878 <=>
879 type_constraint(QueryId, Source, Type, DerivedType).
880
881define_type_from_subquery_with_unspecified_column @
882 derived_query_column(QueryId, _, Column, DerivedType)
883 \
884 type_constraint(QueryId, Source, Type, typeof({no_qualifier}, Column))
885 <=>
886 type_constraint(QueryId, Source, Type, DerivedType).
887
888
889define_type_from_literal @
890 type_constraint(QueryId, Source, Type, typeof({no_qualifier}, literal(Literal, Kind)))
891 <=>
892 ( Literal == '' ->
893 ColumnType = native_type(varchar(1)) 894 ; Kind == string->
895 atom_length(Literal, L),
896 ColumnType = native_type(varchar(L))
897 ; otherwise->
898 ColumnType = native_type(Kind)
899 ),
900 type_constraint(QueryId, Source, Type, ColumnType).
901
902define_type_from_query @
903 query_table(QueryId, TableAlias, identifier(_, TableName))
904 \
905 type_constraint(QueryId, Source, Type, typeof(identifier(_, TableAlias), SourceColumnName))
906 <=>
907 default_schema(Schema),
908 fetch_database_attribute(_, Schema, TableName, SourceColumnName, ColumnType, _, _, _)
909 |
910 type_constraint(QueryId, Source, Type, ColumnType).
911
912define_type_from_query_with_unnamed_table @
913 query_table(QueryId, _, identifier(_, TableName))
914 \
915 type_constraint(QueryId, Source, Type, typeof({no_qualifier}, SourceColumnName))
916 <=>
917 918 default_schema(Schema),
919 920 fetch_database_attribute(_, Schema, TableName, SourceColumnName, ColumnType, _, _, _)
921 922 |
923 type_constraint(QueryId, Source, Type, ColumnType).
924
925define_type_from_uncorrelated_table_with_explicit_reference @ 926 query_table(QueryId, uncorrelated(TableName), _)
927 \
928 type_constraint(QueryId, Source, Type, typeof(identifier(_, TableName), SourceColumnName))
929 <=>
930 default_schema(Schema),
931 fetch_database_attribute(_, Schema, TableName, SourceColumnName, ColumnType, _, _, _)
932 |
933 type_constraint(QueryId, Source, Type, ColumnType).
934
935define_type_from_uncorrelated_table @
936 query_table(QueryId, uncorrelated(TableName), _)
937 \
938 type_constraint(QueryId, Source, Type, typeof(X, SourceColumnName))
939 <=>
940 X \= identifier(_,_),
941 942 default_schema(Schema),
943 fetch_database_attribute(_, Schema, TableName, SourceColumnName, ColumnType, _, _, _)
944 |
945 type_constraint(QueryId, Source, Type, ColumnType).
946
947
948crush_xml_subquery_into_scalar @
949 query_is_xml(SubQueryId),
950 subquery(QueryId, SubQueryId)
951 \
952 type_constraint(QueryId, Source, Type, scalar([merged(_, _, _Subtype)]))
953 <=>
954 sql_explain(crush_xml),
955 type_constraint(QueryId, Source, Type, native_type(nvarchar(max))).
956
957
958crush_subquery_into_scalar @
959 type_constraint(QueryId, Source, Type, scalar([merged(_, _, Subtype)]))
960 <=>
961 sql_explain(crush_subquery),
962 type_constraint(QueryId, Source, Type, Subtype).
963
964concatenate_char @
965 type_merge_hint(Type, Hint),
966 type_constraint(QueryId, Source1, Type, native_type(varchar(N))),
967 type_constraint(QueryId, Source2, Type, native_type(varchar(M)))
968 <=>
969 Hint == add ; Hint == concatenate
970 |
971 ( N == max ->
972 Z = max
973 ; M == max ->
974 Z = max
975 ; otherwise ->
976 Z is min(N+M, 8000)
977 ),
978 sql_explain(concatenate_char),
979 merge_sources(Source1, Source2, Source),
980 type_constraint(QueryId, Source, Type, native_type(varchar(Z))),
981 type_constraint_ready(QueryId, Type).
982
983concatenate_nchar_and_varchar @
984 type_merge_hint(Type, Hint),
985 type_constraint(QueryId, Source1, Type, native_type(nvarchar(N))),
986 type_constraint(QueryId, Source2, Type, native_type(varchar(M)))
987 <=>
988 Hint == add ; Hint == concatenate
989 |
990 ( N == max ->
991 Z = max
992 ; M == max ->
993 Z = max
994 ; otherwise->
995 Z is min(N+M, 8000)
996 ),
997 sql_explain(concatenate_nchar_and_varchar),
998 merge_sources(Source1, Source2, Source),
999 type_constraint(QueryId, Source, Type, native_type(nvarchar(Z))),
1000 type_constraint_ready(QueryId, Type).
1001
1002concatenate_nchar_and_nchar @
1003 type_merge_hint(Type, Hint),
1004 type_constraint(QueryId, Source1, Type, native_type(nvarchar(N))),
1005 type_constraint(QueryId, Source2, Type, native_type(nvarchar(M)))
1006 <=>
1007 Hint == add ; Hint == concatenate
1008 |
1009 ( N == max ->
1010 Z = max
1011 ; M == max ->
1012 Z = max
1013 ; otherwise->
1014 Z is min(N+M, 8000)
1015 ),
1016 sql_explain(concatenate_nchar_and_nchar),
1017 merge_sources(Source1, Source2, Source),
1018 type_constraint(QueryId, Source, Type, native_type(nvarchar(Z))),
1019 type_constraint_ready(QueryId, Type).
1020
1021
1022merge_sized_chars @
1023 type_constraint(QueryId, _, Type, native_type(varchar(N)))
1024 \
1025 type_merge_hint(Type, sized_varchar),
1026 type_constraint(QueryId, _, Type, native_type(varchar(M)))
1027 <=>
1028 ( integer(N), integer(M), N < M )
1029 |
1030 sql_explain(merge_sized_chars),
1031 type_constraint_ready(QueryId, Type).
1032
1033union_chars @
1034 type_constraint(QueryId, _, Type, native_type(varchar(N)))
1035 \
1036 type_merge_hint(Type, Hint),
1037 type_constraint(QueryId, _, Type, native_type(varchar(M)))
1038 <=>
1039 Hint \== concatenate,
1040 ( N == max
1041 ; M == max
1042 ; N >= M
1043 )
1044 |
1045 sql_explain(union_chars(N, M)),
1046 type_constraint_ready(QueryId, Type).
1047
1048union_nchars @
1049 type_constraint(QueryId, _, Type, native_type(nvarchar(N)))
1050 \
1051 type_merge_hint(Type, Hint),
1052 type_constraint(QueryId, _, Type, native_type(nvarchar(M)))
1053 <=>
1054 Hint \== concatenate,
1055 ( N == max
1056 ; M == max
1057 ; N >= M
1058 )
1059 |
1060 sql_explain(union_nchars),
1061 type_constraint_ready(QueryId, Type).
1062
1063union_nchar_and_varchar @
1064 type_merge_hint(Type, Hint),
1065 type_constraint(QueryId, Source1, Type, native_type(nvarchar(N))),
1066 type_constraint(QueryId, Source2, Type, native_type(varchar(M)))
1067 <=>
1068 Hint \== concatenate
1069 |
1070 ( N == max->
1071 Z = max
1072 ; M == max->
1073 Z = max
1074 ; otherwise->
1075 Z is max(N, M)
1076 ),
1077 sql_explain(union_nchar_and_varchar),
1078 merge_sources(Source1, Source2, Source),
1079 type_constraint(QueryId, Source, Type, native_type(nvarchar(Z))),
1080 type_constraint_ready(QueryId, Type).
1081
1082
1083
1084expand_precision_integer_to_decimal @ 1085 type_constraint(QueryId, Source1, Type, native_type(decimal(_, _)))
1086 \
1087 type_constraint(QueryId, Source2, Type, native_type(int(N)))
1088 <=>
1089 sql_explain(precision_integer_to_decimal(N,0)),
1090 merge_sources(Source1, Source2, Source),
1091 type_constraint(QueryId, Source, Type, native_type(decimal(N, 0))).
1092
1093expand_precision_integer_to_general_integer @
1094 type_constraint(QueryId, _, Type, native_type(int))
1095 \
1096 type_merge_hint(Type, _),
1097 type_constraint(QueryId, _, Type, native_type(int(_)))
1098 <=>
1099 sql_explain(precision_integer_to_int),
1100 type_constraint_ready(QueryId, Type).
1101
1102
1103expand_integer_to_decimal @
1104 type_merge_hint(Type, union),
1105 type_constraint(QueryId, Source1, Type, native_type(decimal(_, _)))
1106 \
1107 type_constraint(QueryId, Source2, Type, native_type(int))
1108 <=>
1109 sql_explain(integer_to_decimal_for_union),
1110 merge_sources(Source1, Source2, Source),
1111 type_constraint(QueryId, Source, Type, native_type(decimal(10,0))).
1112
1113expand_tinyint_to_int @
1114 type_constraint(QueryId, _, Type, native_type(int))
1115 \
1116 type_merge_hint(Type, _),
1117 type_constraint(QueryId, _, Type, native_type(tinyint))
1118 <=>
1119 sql_explain(tinyint_to_int),
1120 type_constraint_ready(QueryId, Type).
1121
1122expand_tinyint_to_precision_int @
1123 type_constraint(QueryId, _, Type, native_type(int(_)))
1124 \
1125 type_merge_hint(Type, _),
1126 type_constraint(QueryId, _, Type, native_type(tinyint))
1127 <=>
1128 sql_explain(tinyint_to_precision_integer),
1129 type_constraint_ready(QueryId, Type).
1130
1131
1132expand_int_to_float @
1133 type_constraint(QueryId, _, Type, native_type(float(_)))
1134 \
1135 type_merge_hint(Type, _),
1136 type_constraint(QueryId, _, Type, native_type(int))
1137 <=>
1138 sql_explain(int_to_float),
1139 type_constraint_ready(QueryId, Type).
1140
1142quirk_tinyint_and_varchar_is_tinyint @
1143 type_constraint(QueryId, _, Type, native_type(tinyint))
1144 \
1145 type_merge_hint(Type, _),
1146 type_constraint(QueryId, _, Type, native_type(varchar(_)))
1147 <=>
1148 sql_explain(tinyint_and_varchar),
1149 type_constraint_ready(QueryId, Type).
1150
1151max_varchars @
1152 type_constraint(QueryId, _, Type, native_type(varchar(A)))
1153 \
1154 type_merge_hint(Type, max),
1155 type_constraint(QueryId, _, Type, native_type(varchar(B)))
1156 <=>
1157 integer(A), integer(B), A >= B
1158 |
1159 sql_explain(max_varchars),
1160 type_constraint_ready(QueryId, Type).
1161
1162max_nvarchar_with_varchar @
1163 type_merge_hint(Type, max),
1164 type_constraint(QueryId, Source1, Type, native_type(nvarchar(A))),
1165 type_constraint(QueryId, Source2, Type, native_type(varchar(B)))
1166 <=>
1167 ( ( A == max ; B == max)->
1168 C = max
1169 ; otherwise->
1170 C is max(A, B)
1171 ),
1172 sql_explain(max_vvarchar_with_varchar),
1173 merge_sources(Source1, Source2, Source),
1174 type_constraint(QueryId, Source, Type, native_type(nvarchar(C))),
1175 type_constraint_ready(QueryId, Type).
1176
1177
1178str_expression_with_int @
1179 type_merge_hint(Type, str),
1180 type_constraint(QueryId, Source1, Type, native_type(int)),
1181 type_constraint(QueryId, Source2, Type, native_type(varchar(A)))
1182 <=>
1183 ( A == max ->
1184 B = max
1185 ; otherwise ->
1186 B is max(A, 10)
1187 ),
1188 sql_explain(str_expression_with_int),
1189 merge_sources(Source1, Source2, Source),
1190 type_constraint(QueryId, Source, Type, native_type(varchar(B))),
1191 type_constraint_ready(QueryId, Type).
1192
1194quirk_int_and_varchar_is_int @
1195 type_constraint(QueryId, Source1, Type, native_type(int))
1196 \
1197 type_merge_hint(Type, _),
1198 type_constraint(QueryId, Source2, Type, native_type(varchar(_)))
1199 <=>
1200 sql_explain(int_and_varchar),
1201 type_mismatch(Source1, Source2, int, varchar),
1202 type_constraint_ready(QueryId, Type).
1203
1204quirk_int_and_varchar_is_int @
1205 type_constraint(QueryId, Source1, Type, native_type(int(_)))
1206 \
1207 type_merge_hint(Type, _),
1208 type_constraint(QueryId, Source2, Type, native_type(varchar(_)))
1209 <=>
1210 sql_explain(int_and_varchar),
1211 type_mismatch(Source1, Source2, int, varchar),
1212 type_constraint_ready(QueryId, Type).
1213
1214
1216quirk_datetime_and_int_is_int @
1217 type_constraint(QueryId, _, Type, native_type(datetime))
1218 \
1219 type_merge_hint(Type, _),
1220 type_constraint(QueryId, _, Type, native_type(int))
1221 <=>
1222 sql_explain(datetime_and_int),
1223 type_constraint_ready(QueryId, Type).
1224
1226quirk_datetime_and_precision_int_is_precision_int @
1227 type_constraint(QueryId, _, Type, native_type(datetime))
1228 \
1229 type_merge_hint(Type, _),
1230 type_constraint(QueryId, _, Type, native_type(int(_)))
1231 <=>
1232 sql_explain(datetime_and_precision_int),
1233 type_constraint_ready(QueryId, Type).
1234
1235
1236integer_addition @
1237 type_constraint(QueryId, _, Type, native_type(int))
1238 \
1239 type_merge_hint(Type, Hint),
1240 type_constraint(QueryId, _, Type, native_type(int))
1241 <=>
1242 memberchk(Hint, [add, subtract, concatenate])
1243 |
1244 sql_explain(integer_addition),
1245 type_constraint_ready(QueryId, Type).
1246
1247integer_multiplication_requires_promotion @
1248 type_merge_hint(Type, Hint)
1249 \
1250 type_constraint(QueryId, Source, Type, native_type(int))
1251 <=>
1252 memberchk(Hint, [multiply, divide(_)])
1253 |
1254 sql_explain(promote_int_for_multiplication),
1255 type_constraint(QueryId, Source, Type, native_type(decimal(10,0))).
1256
1257
1258integer_and_decimal_arithmetic @
1259 type_merge_hint(Type, Hint),
1260 type_constraint(QueryId, Source1, Type, native_type(decimal(_, _)))
1261 \
1262 type_constraint(QueryId, Source2, Type, native_type(int))
1263 <=>
1264 Hint \== union
1265 |
1266 sql_explain(promote_int_to_decimal_for_arithmetic(Hint)),
1267 merge_sources(Source1, Source2, Source),
1268 type_constraint(QueryId, Source, Type, native_type(decimal(10,0))).
1269
1270
1271expand_type_scope_decimal_with_hint @
1272 type_merge_hint(Type, Hint),
1273 type_constraint(QueryId, Source1, Type, native_type(decimal(P1, S1))),
1274 type_constraint(QueryId, Source2, Type, native_type(decimal(P2, S2)))
1275 <=>
1276 ( Hint == multiply->
1277 P is P1 + P2 + 1,
1278 S is S1 + S2
1279 ; ( Hint == add ; Hint == concatenate) -> 1280 P is max(S1, S2) + max(P1-S1, P2-S2) + 1,
1281 S is max(S1, S2)
1282 ; Hint == subtract ->
1283 P is max(S1, S2) + max(P1-S1, P2-S2) + 1,
1284 S is max(S1, S2)
1285 ; Hint = divide(DA)->
1286 ( DA = node(Divisor, _, _, _, _) ->
1287 true
1288 ; otherwise->
1289 Divisor = DA
1290 ),
1291 1292 1293 ( Divisor = domain(D) ->
1294 fetch_domain_data_type(D, V)
1295 ; Divisor = native_type(V)->
1296 true
1297 ; otherwise->
1298 throw(bad_divisor(Divisor))
1299 ),
1300 ( ( ( V = int(P1), S1 == 0) 1301 ;
1302 V == decimal(P1, S1))->
1303
1304 1305 P is P2 - S2 + S1 + max(6, S2 + P1 + 1),
1306 S is max(6, S2 + P1 + 1)
1307 ; otherwise->
1308 1309 P is P1 - S1 + S2 + max(6, S1 + P2 + 1),
1310 S is max(6, S1 + P2 + 1)
1311 )
1312 ; Hint == union->
1313 P is max(S1, S2) + max(P1-S1, P2-S2),
1314 S is max(S1, S2)
1315 ; otherwise->
1316 throw(unhandled_scope(Hint))
1317 ),
1318 ( P > 38 ->
1319 Px = 38,
1320 1321 1322 1323 ( memberchk(Hint, [add, concatenate, subtract])->
1324 Sx is max(0, S - (P-39))
1325 ; Hint == union->
1326 Sx is max(0, S - (P-38))
1327 ; max(0, S-(P-38)) < 6->
1328 Sx is min(S, 6)
1329 ; otherwise->
1330 Sx is max(0, S - (P-38))
1331 )
1332 ; otherwise->
1333 Px = P,
1334 Sx = S
1335 ),
1336 sql_explain(decimal_arithmetic(Hint, Px, Sx)),
1337 merge_sources(Source1, Source2, Source),
1338 type_constraint(QueryId, Source, Type, native_type(decimal(Px, Sx))),
1339 type_constraint_ready(QueryId, Type).
1340
1341resolve_types @
1342 resolve_types(QueryId)
1343 <=>
1344 commit(QueryId).
1345
1346resolve_unions @
1347 commit(QueryId)
1348 \
1349 union_type(QueryId, L, R, T)
1350 <=>
1351 is_list(L),
1352 is_list(R)
1353 |
1354 ( resolve_union_type(QueryId, L, R, T)->
1355 true
1356 ; otherwise->
1357 format(atom(Message), 'Could not determine the type of the union of ~w and ~w', [L, R]),
1358 throw(cql_error(failed_to_resolve_union, Message))
1359 ).
1360
1361resolve_derived_tables @
1362 commit(QueryId),
1363 derived_table(QueryId, Table, Constraint)
1364 <=>
1365 is_list(Constraint)
1366 |
1367 create_derived_table(QueryId, Table, Constraint),
1368 commit(QueryId).
1369
1370union_of_type_decimal_domains_is_not_a_domain @
1371 commit(QueryId), 1372 type_merge_hint(Type, union),
1373 type_constraint(QueryId, Source1, Type, domain(D1)),
1374 type_constraint(QueryId, Source2, Type, domain(D2))
1375 <=>
1376 fetch_domain_data_type(D1, decimal(A1, A2)),
1377 fetch_domain_data_type(D2, decimal(B1, B2))
1378 |
1379 sql_explain(union_domains),
1380 most_general_type(QueryId, Source1, Source2, decimal(A1, A2), decimal(B1, B2), union, Type),
1381 commit(QueryId).
1382
1383merge_domains @
1384 commit(QueryId), 1385 type_merge_hint(Type, Hint),
1386 type_constraint(QueryId, Source1, Type, domain(D1)),
1387 type_constraint(QueryId, Source2, Type, domain(D2))
1388 <=>
1389 fetch_domain_data_type(D1, T1),
1390 fetch_domain_data_type(D2, T2)
1391 |
1392 ( T1 = decimal(_, _),
1393 T2 = decimal(_, _)->
1394 most_general_type(QueryId, Source1, Source2, T1, T2, Hint, Type)
1395 ; T1 = datetime, T2 = datetime, memberchk(Hint, [add, subtract, concatenate])->
1396 type_constraint(QueryId, Source1, Type, native_type(datetime)),
1397 type_constraint_ready(QueryId, Type)
1398 ; D1 == D2, Hint \== concatenate->
1399 type_constraint(QueryId, Source1, Type, domain(D1)),
1400 type_constraint_ready(QueryId, Type)
1401 ; otherwise->
1402 most_general_type(QueryId, Source1, Source1, T1, T2, Hint, Type)
1403 ),
1404 sql_explain(join_domains_for(Hint, D1, D2, Type)),
1405 commit(QueryId).
1406
1407merge_domain_to_native @
1408 commit(QueryId), 1409 type_merge_hint(Type, Hint),
1410 type_constraint(QueryId, Source1, Type, domain(D)),
1411 type_constraint(QueryId, Source2, Type, native_type(NT))
1412 <=>
1413 fetch_domain_data_type(D, T)
1414 |
1415 sql_explain(join_domain_to_native),
1416 most_general_type(QueryId, Source1, Source2, T, NT, Hint, Type),
1417 commit(QueryId).
1418
1419drop_nulltype_in_favour_of_domain @
1420 1421 type_merge_hint(Type, _Anything),
1422 type_constraint(QueryId, Source1, Type, domain(D)),
1423 type_constraint(QueryId, Source2, Type, {nulltype})
1424 <=>
1425 sql_explain(drop_nulltype_for_domain),
1426 fetch_domain_data_type(D, T),
1427 merge_sources(Source1, Source2, Source),
1428 type_constraint(QueryId, Source, Type, native_type(T)),
1429 type_constraint_ready(QueryId, Type).
1430
1431drop_nulltype_in_favour_of_native_type @
1432 type_constraint(QueryId, _, Type, native_type(T))
1433 \
1434 type_merge_hint(Type, Hint),
1435 type_constraint(QueryId, _, Type, {nulltype})
1436 <=>
1437 sql_explain(drop_nulltype_for_native(T, Hint)),
1438 type_constraint_ready(QueryId, Type).
1439
1440
1451drop_nulltype_in_favour_of_another_nulltype @
1452 type_constraint(QueryId, _, Type, {nulltype})
1453 \
1454 type_merge_hint(Type, Hint),
1455 type_constraint(QueryId, _, Type, {nulltype})
1456 <=>
1457 ( Hint == union ->
1458 ( prolog_load_context(file, _Filename)->
1459 true
1460 1461 ; otherwise->
1462 true
1463 )
1464 ; otherwise->
1465 true
1466 ),
1467 sql_explain(drop_nulltype_for_nulltype(Hint)),
1468 type_constraint_ready(QueryId, Type).
1469
1470force_type_not_domain @
1471 1472 force_type_not_domain(Type),
1473 type_constraint(QueryId, Source, Type, domain(D))
1474 <=>
1475 fetch_domain_data_type(D, decimal(P, S))
1476 |
1477 sql_explain(forcing_decimal_not_domain(D)),
1478 type_constraint(QueryId, Source, Type, native_type(decimal(P, S))).
1479
1480force_type_not_domain @
1481 1482 force_type_not_domain(Type),
1483 type_constraint(QueryId, Source, Type, domain(D))
1484 <=>
1485 fetch_domain_data_type(D, varchar(L))
1486 |
1487 sql_explain(forcing_varchar_not_domain(D)),
1488 type_constraint(QueryId, Source, Type, native_type(varchar(L))).
1489
1490force_type_not_domain @
1491 force_type_not_domain(Type),
1492 type_constraint(QueryId, Source, Type, domain(D))
1493 <=>
1494 fetch_domain_data_type(D, datetime)
1495 |
1496 sql_explain(forcing_datetime_not_domain(D)),
1497 type_constraint(QueryId, Source, Type, native_type(datetime)).
1498
1499
1500rounded_int_is_decimal @ 1501 type_merge_hint(Type, round),
1502 type_constraint(QueryId, Source, Type, native_type(int))
1503 <=>
1504 sql_explain(rounded_int_is_decimal),
1505 type_constraint(QueryId, Source, Type, native_type(decimal(10,0))).
1506
1507rounded_decimal_has_no_scale @
1508 type_merge_hint(Type, round),
1509 type_constraint(QueryId, Source, Type, native_type(decimal(P, _)))
1510 <=>
1511 sql_explain(rounded_decimal_has_no_scale),
1512 type_constraint(QueryId, Source, Type, native_type(decimal(P,0))).
1513
1514
1515force_domain_type_to_sum @
1516 1517 type_merge_hint(Type, sum),
1518 type_constraint(QueryId, Source, Type, domain(D))
1519 <=>
1520 fetch_domain_data_type(D, decimal(_, S))
1521 |
1522 sql_explain(forcing_domain_to_sum(D)),
1523 type_constraint(QueryId, Source, Type, native_type(decimal(38, S))).
1524
1525force_domain_type_to_avg @
1526 1527 type_merge_hint(Type, avg),
1528 type_constraint(QueryId, Source, Type, domain(D))
1529 <=>
1530 sql_explain(forcing_domain_to_avg(D)),
1531 type_constraint(QueryId, Source, Type, native_type(decimal(38, 6))).
1532
1533force_native_type_to_sum @
1534 1535 type_merge_hint(Type, sum),
1536 type_constraint(QueryId, Source, Type, native_type(decimal(_, S)))
1537 <=>
1538 sql_explain(forcing_native_to_sum),
1539 type_constraint(QueryId, Source, Type, native_type(decimal(38, S))).
1540
1541force_native_type_to_avg @
1542 1543 type_merge_hint(Type, avg),
1544 type_constraint(QueryId, Source, Type, native_type(decimal(_, _)))
1545 <=>
1546 sql_explain(forcing_native_to_avg),
1547 type_constraint(QueryId, Source, Type, native_type(decimal(38, 6))).
1548
1549union_precision_ints @
1550 type_merge_hint(Type, union),
1551 type_constraint(QueryId, Source1, Type, native_type(int(_))),
1552 type_constraint(QueryId, Source2, Type, native_type(int(_)))
1553 <=>
1554 sql_explain(union_precision_ints),
1555 merge_sources(Source1, Source2, Source),
1556 type_constraint(QueryId, Source, Type, native_type(int)),
1557 type_constraint_ready(QueryId, Type).
1558
1559union_identical_natives @
1560 type_constraint(QueryId, _, Type, native_type(T))
1561 \
1562 type_merge_hint(Type, union),
1563 type_constraint(QueryId, _, Type, native_type(T))
1564 <=>
1565 sql_explain(union_identical_natives(T)),
1566 type_constraint_ready(QueryId, Type).
1567
1568merge_datetime_and_int @
1569 type_merge_hint(Type, _Hint),
1570 type_constraint(QueryId, Source1, Type, native_type(datetime)),
1571 type_constraint(QueryId, Source2, Type, native_type(decimal(_,_)))
1572 <=>
1573 sql_explain(operation_with_datetime_and_decimal),
1574 merge_sources(Source1, Source2, Source),
1575 type_constraint(QueryId, Source, Type, native_type(datetime)),
1576 type_constraint_ready(QueryId, Type).
1577
1578union_of_datetime_and_date_is_datetime @
1579 type_merge_hint(Type, union),
1580 type_constraint(QueryId, Source, Type, native_type(datetime))
1581 \
1582 type_constraint(QueryId, Source, Type, native_type(date))
1583 <=>
1584 sql_explain(union_of_datetime_and_date),
1585 type_constraint_ready(QueryId, Type).
1586
1587
1588accept_domain @
1589 type_constraint(QueryId, _, Type, domain(Domain)),
1590 type_constraint_ready(QueryId, Type)
1591 <=>
1592 sql_explain(accepting(domain(Domain), Type)),
1593 Type = domain(Domain).
1594
1595accept_native_type @
1596 type_constraint(QueryId, _, Type, native_type(Native)),
1597 type_constraint_ready(QueryId, Type)
1598 <=>
1599 sql_explain(accepting(native_type(Native), Type)),
1600 Type = native_type(Native).
1601
1602accept_nulltype @
1603 type_constraint(QueryId, _, Type, {nulltype}),
1604 type_constraint_ready(QueryId, Type)
1605 <=>
1606 sql_explain(accepting_nulltype(Type)),
1607 Type = {nulltype}.
1608
1609
1610find_column_types @
1611 query_table(QueryId, _, identifier(_, TableName)),
1612 find_all_column_types(QueryId, Source, Tail)
1613 <=>
1614 default_schema(Schema),
1615 findall(merged(ColumnName, Source, Domain),
1616 fetch_database_attribute(_, Schema, TableName, ColumnName, Domain, _, _, _),
1617 Columns),
1618 create_column_constraints(QueryId, Source, Columns, Tail, NewTail),
1619 find_all_column_types(QueryId, Source, NewTail).
1620
1621find_column_types @
1622 derived_query_column(QueryId, _, Column, ColumnType),
1623 find_all_column_types(QueryId, Source, Tail)
1624 <=>
1625 Tail = [merged(Column, Source, ColumnType)|NewTail],
1626 find_all_column_types(QueryId, Source, NewTail).
1627
1628share_commit @
1629 commit(Parent),
1630 subquery(Parent, Child)
1631 ==>
1632 commit(Child).
1633
1634commit_peers @
1635 commit(Qid),
1636 peer_query(Qid, Sibling)
1637 ==>
1638 commit(Sibling).
1639
1640
1641share_table @
1642 subquery(Parent, Child),
1643 query_table(Parent, A, B)
1644 ==>
1645 query_table(Child, A, B).
1646
1652
1653finished_finding @
1654 commit(QueryId)
1655 \
1656 find_all_column_types(QueryId, _, Tail)
1657 <=>
1658 Tail = [].
1659
1669
1670frozen_reverse @
1671 frozen_reverse(_, A, B)
1672 <=>
1673 is_list(A)
1674 |
1675 A = B.
1677
1678cleanup @ cleanup(QueryId) \ frozen_reverse(QueryId, _, _) <=> true.
1679cleanup @ cleanup(QueryId) \ type_constraint(QueryId, _, _, _) <=> true. 1680cleanup @ cleanup(_QueryId) \ type_constraint_ready(_, _) <=> true.
1681cleanup @ cleanup(_QueryId) \ type_merge_hint(_, _) <=> true.
1682cleanup @ cleanup(QueryId) \ query_table(QueryId, _, _) <=> true.
1683cleanup @ cleanup(QueryId) \ derived_query_column(QueryId, _, _, _) <=> true.
1684cleanup @ cleanup(QueryId) \ subquery(QueryId, SubQueryId) <=> cleanup(SubQueryId).
1685cleanup @ cleanup(QueryId) \ peer_query(QueryId, PeerQueryId) <=> cleanup(PeerQueryId).
1686cleanup @ cleanup(QueryId) \ query_is_xml(QueryId) <=> true.
1687cleanup @ cleanup(QueryId) \ commit(QueryId) <=> true.
1688cleanup @ cleanup(QueryId) \ find_all_column_types(QueryId, _, _) <=> true.
1689cleanup @ cleanup(QueryId) \ subquery(SubQueryId, QueryId) <=> cleanup(SubQueryId).
1691cleanup @ cleanup(_) <=> true.
1692
1693create_column_constraints(_QueryId, _Source, [], NewTail, NewTail):- !.
1694create_column_constraints(QueryId, Source, [merged(Name, Source, Domain)|Columns], [merged(Name, Source, Type)|T], NewTail):-
1695 type_constraint(QueryId, Source, Type, Domain),
1696 type_constraint_ready(QueryId, Type),
1697 create_column_constraints(QueryId, Source, Columns, T, NewTail).
1698
1699
1700resolve_union_type(_QueryId, [], [], []):- !.
1701resolve_union_type(_QueryId, A, [], []):- throw(union_mismatch(left(A))).
1702resolve_union_type(_QueryId, [], A, []):- throw(union_mismatch(right(A))).
1703resolve_union_type(QueryId, [merged(NameA, SourceA, TypeA)|As], [merged(NameB, SourceB, TypeB)|Bs], [merged(Name, SourceA, C)|Cs]):-
1704 1705 1706 1707 ( nonvar(TypeA),
1708 TypeA = domain(X),
1709 nonvar(TypeB),
1710 TypeB = domain(X),
1711 fetch_domain_data_type(X, decimal(P, S))->
1712 C = native_type(decimal(P,S))
1713 ; otherwise->
1714 type_merge_hint(C, union),
1715 type_constraint(QueryId, SourceA, C, TypeA),
1716 type_constraint(QueryId, SourceB, C, TypeB)
1717 ),
1718 ( NameA == {no_alias} ->
1719 name_from_identifier(NameB, Name)
1720 ; otherwise->
1721 name_from_identifier(NameA, Name)
1722 ),
1723 resolve_union_type(QueryId, As, Bs, Cs).
1724
1725
1726name_from_identifier(literal(NameMC, _), Name):- !,
1727 downcase_atom(NameMC, Name).
1728name_from_identifier({no_alias}, {no_alias}):- !.
1729name_from_identifier(Identifier, Name):-
1730 downcase_atom(Identifier, Name).
1731
1732
1733
1734
1735check_types(_, _).
1736most_general_type(QueryId, S1, S2, A, B, Op, C):-
1737 type_merge_hint(C, Op),
1738 ( var(A)->
1739 type_constraint(QueryId, S1, C, A)
1740 ; otherwise->
1741 strip_sql_comments(A, AA),
1742 ( AA = native_type(AAA)->
1743 type_constraint(QueryId, S1, C, native_type(AAA))
1744 ; AA = domain(AAA)->
1745 type_constraint(QueryId, S1, C, domain(AAA))
1746 ; AA == {nulltype}->
1747 type_constraint(QueryId, S1, C, {nulltype})
1748 ; otherwise->
1749 type_constraint(QueryId, S1, C, native_type(AA))
1750 )
1751 ),
1752 ( var(B)->
1753 type_constraint(QueryId, S2, C, B)
1754 ; otherwise->
1755 strip_sql_comments(B, BB),
1756 ( BB = native_type(BBB)->
1757 type_constraint(QueryId, S2, C, native_type(BBB))
1758 ; BB = domain(BBB)->
1759 type_constraint(QueryId, S2, C, domain(BBB))
1760 ; BB == {nulltype}->
1761 type_constraint(QueryId, S2, C, {nulltype})
1762 ; otherwise->
1763 type_constraint(QueryId, S2, C, native_type(BB))
1764 )
1765 ).
1766
1768coalesce_type(QueryId, [A, B], [S1, S2], T):- !,
1769 most_general_type(QueryId, S1, S2, A, B, union, T).
1770coalesce_type(QueryId, [A], [S1], T):- !,
1771 type_constraint(QueryId, S1, T, A),
1772 type_constraint_ready(QueryId, T).
1773coalesce_type(QueryId, [A, B|Xs], [S1, S2|Ss], T):-
1774 most_general_type(QueryId, S1, S2, A, B, union, AB),
1775 coalesce_type(QueryId, Xs, Ss, XT),
1776 most_general_type(QueryId, S2, S2, AB, XT, union, T).
1777
1778concatenate_type(QueryId, S1, S2, A, B, C):-
1779 type_merge_hint(C, concatenate),
1780 type_constraint(QueryId, S1, C, A),
1781 type_constraint(QueryId, S2, C, B).
1782
1783
1784merge_types(all, _, Types, Types):- !.
1785merge_types([], [], [], []):- !.
1786merge_types([derived_column(From, Alias)|As], [S|Ss], [B|Bs], [merged(Name, S, B)|Cs]):-
1787 ( Alias == {no_alias},
1788 From = column(_Qualifier, Name)->
1789 true
1790 ; otherwise->
1791 name_from_identifier(Alias, Name)
1792 ),
1793 merge_types(As, Ss, Bs, Cs).
1794
1795
1796determine_tables(_, Var):- var(Var), !, throw(var).
1797determine_tables(_, []):- !.
1798determine_tables(QueryId, [A|B]):- !,
1799 determine_tables(QueryId, A),
1800 determine_tables(QueryId, B).
1801
1802determine_tables(QueryId, join(LHS, RHS)):- !,
1803 determine_tables(QueryId, LHS),
1804 determine_tables(QueryId, RHS).
1805determine_tables(QueryId, correlated_table(table(Identifier), {no_correlation})):- !,
1806 Identifier = identifier(_, TableName), !,
1807 query_table(QueryId, uncorrelated(TableName), Identifier).
1808determine_tables(QueryId, correlated_table(table(Identifier), correlation(Correlation, _))):- !,
1809 query_table(QueryId, Correlation, Identifier).
1810determine_tables(QueryId, qualified_join(_Type, RHS, _On)):- !,
1811 determine_tables(QueryId, RHS).
1812determine_tables(QueryId, cross_join(RHS)):- !,
1813 determine_tables(QueryId, RHS).
1814determine_tables(QueryId, derived_table(_Derivation, correlation(DerivedTableName, _), T)):- !,
1815 derived_table(QueryId, DerivedTableName, T).
1816
1817determine_tables(_, X):- throw(determine_tables(X)).
1818
1819
1820create_derived_table(_QueryId, _DerivedTableName, []):- !.
1821create_derived_table(QueryId, DerivedTableName, [merged(Name, _, Type)|Columns]):- !,
1822 derived_query_column(QueryId, DerivedTableName, Name, Type),
1823 create_derived_table(QueryId, DerivedTableName, Columns).
1824
1826fetch_domain_data_type(identifier(_, Domain), Type):-
1827 !,
1828 fetch_domain_data_type(Domain, Type).
1829fetch_domain_data_type(Domain, Type):-
1830 domain_database_data_type(Domain, Type).
1831
1832fetch_database_attribute(_, Schema, TableName, _, _, _, _, _):-
1833 \+system_table(TableName, _, _),
1834 \+database_attribute(_, Schema, TableName, _, _, _, _, _),
1835 !,
1836 format(atom(Message), 'View references entity ~w which does not exist', [TableName]),
1837 throw(cql_error(no_such_entity, Message)).
1838
1839fetch_database_attribute(_, Schema, TableName, ColumnName, Domain, _, _, _):-
1840 system_table(TableName, ColumnName, Domain)
1841 ;
1842 database_attribute(_, Schema, TableName, ColumnName, Domain, _, _, _).
1843
1844
1845system_table(sysobjects, name, native_type(nvarchar(128))).
1846system_table(sysobjects, name, native_type(nvarchar(128))).
1847system_table(sysobjects, xtype, native_type(char(2))).
1848system_table(sysobjects, xtype, native_type(nvarchar(128))).
1849system_table(sysobjects, id, native_type(int)).
1850system_table(sysobjects, uid, native_type(smallint)).
1851system_table(sysobjects, parent_obj, native_type(int)).
1852system_table(syscolumns, name, native_type(nvarchar(128))).
1853system_table(syscolumns, colid, native_type(smallint)).
1854system_table(syscolumns, id, native_type(int)).
1855system_table(sysconstraints, colid, native_type(smallint)).
1856system_table(sysconstraints, constid, native_type(int)).
1857system_table(syscomments, id, native_type(int)).
1858system_table(syscomments, text, native_type(nvarchar(4000))).
1859system_table(syscomments, colid, native_type(smallint)).
1860
1861system_table(table_constraints, constraint_catalog, native_type(nvarchar(128))).
1862system_table(table_constraints, constraint_schema, native_type(nvarchar(128))).
1863system_table(table_constraints, constraint_name, native_type(nvarchar(128))).
1864system_table(table_constraints, constraint_type, native_type(varchar(11))).
1865system_table(table_constraints, table_catalog, native_type(nvarchar(128))).
1866system_table(table_constraints, table_schema, native_type(nvarchar(128))).
1867system_table(table_constraints, table_name , native_type(nvarchar(128))).
1868
1869system_table(key_column_usage, constraint_name, native_type(nvarchar(128))).
1870system_table(key_column_usage, table_catalog, native_type(nvarchar(128))).
1871system_table(key_column_usage, table_schema, native_type(nvarchar(128))).
1872system_table(key_column_usage, table_name, native_type(nvarchar(128))).
1873system_table(key_column_usage, column_name, native_type(nvarchar(128))).
1874system_table(key_column_usage, ordinal_position, native_type(int)).
1875
1876system_table(referential_constraints, constraint_name, native_type(nvarchar(128))).
1877system_table(referential_constraints, constraint_catalog, native_type(nvarchar(128))).
1878system_table(referential_constraints, constraint_schema, native_type(nvarchar(128))).
1879system_table(referential_constraints, unique_constraint_name, native_type(nvarchar(128))).
1880system_table(referential_constraints, unique_constraint_catalog, native_type(nvarchar(128))).
1881system_table(referential_constraints, unique_constraint_schema, native_type(nvarchar(128))).
1882
1883
1884left_factor_types(Qid, In, T):-
1885 left_factor2(In, Left),
1886 resolve_factored_types(Qid, Left, T).
1887
1888resolve_factored_types(_Qid, Var, Var):- var(Var), !.
1889resolve_factored_types(Qid, node(A, AS, Op, B, BS), T):- !,
1890 most_general_type(Qid, AS, BS, AT, B, Op, T),
1891 resolve_factored_types(Qid, A, AT).
1892resolve_factored_types(_Qid, T, T).
1893
1895left_factor2(A, A):- var(A), !.
1896left_factor2(node(A, AS, Op, B, BS), Y):- !, left_factor_appending2(B, BS, A, AS, Op, Y).
1897left_factor2(A, A).
1898left_factor_appending2(Var, VarS, T, TS, Op, node(T, TS, Op, Var, VarS)):- var(Var), !.
1899left_factor_appending2(node(A, AS, Op1, B, BS), NS, T, TS, Op2, Z):- !, left_factor_appending2(B, BS, node(T, TS, Op2, A, AS), NS, Op1, Z).
1900left_factor_appending2(X, XS, Y, YS, Op, node(Y, YS, Op, X, XS)).
1901
1902
1903
(Var, Var):- var(Var), !. 1905strip_sql_comments(meta(_,_):A, B):- !,
1906 strip_sql_comments(A, B).
1907
1908strip_sql_comments(A, B):-
1909 A =.. [Functor|Args], Args \== [], !,
1910 strip_sql_comments_list(Args, Args2),
1911 B =.. [Functor|Args2].
1912
1913strip_sql_comments(A, A):- !.
1914
([], []):- !.
1916strip_sql_comments_list([A|B], [C|D]):- !, strip_sql_comments(A, C), strip_sql_comments_list(B, D).
1917
1918consolidate_errors(Var):-
1919 var(Var),
1920 throw(instantiation_error(Var)).
1921consolidate_errors(meta(_Comments, ErrorGroup):A):- !,
1922 ( ErrorGroup = {null} ->
1923 true
1924 ; otherwise->
1925 true 1926 ),
1927 consolidate_errors(A).
1928consolidate_errors(A):-
1929 A =.. [_|Args], Args \== [], !,
1930 consolidate_errors_list(Args).
1931consolidate_errors(_):- !.
1932
1933consolidate_errors_list([]):- !.
1934consolidate_errors_list([A|B]):- !, consolidate_errors(A), consolidate_errors_list(B).
1935
1936
1937not_a_builtin_function(DBMS, Function):-
1938 strip_sql_comments(Function, identifier(Schema, Functor)),
1939 \+once(builtin_function(DBMS, Schema, Functor)).
1940
1941builtin_function('Microsoft SQL Server', _, month).
1942builtin_function('Microsoft SQL Server', _, day).
1943builtin_function('Microsoft SQL Server', _, year).
1944builtin_function('Microsoft SQL Server', _, round).
1945builtin_function('Microsoft SQL Server', _, floor).
1946builtin_function('Microsoft SQL Server', _, ceiling).
1947builtin_function('Microsoft SQL Server', _, len).
1948builtin_function('Microsoft SQL Server', _, rtrim).
1949builtin_function('Microsoft SQL Server', _, str).
1950builtin_function('Microsoft SQL Server', _, datename).
1951builtin_function('Microsoft SQL Server', _, getdate).
1952
1953builtin_function('Microsoft SQL Server', _, db_name).
1954builtin_function('Microsoft SQL Server', _, permissions).
1955builtin_function('Microsoft SQL Server', _, user_name).
1956
1957routine_type(Name, Type):-
1958 1959 1960 default_schema(Schema),
1961 dbms(Schema, DBMS),
1962 strip_sql_comments(Name, identifier(_, Identifier)),
1963 ( cql_normalize_name(DBMS, Identifier, NormalizedName),
1964 routine_return_type(Schema, NormalizedName, Type),
1965 Type \== void->
1966 true
1967 ; otherwise->
1968 format(atom(Message), 'Could not determine the type of SQL function ~w', [Identifier]),
1969 throw(cql_error(cannot_determine_function_type, Message))
1970 ).
1971
1972merge_sources(S, S, S):- !.
1973merge_sources(A, B, _):-
1974 format(atom(Message), '~w vs ~w', [A, B]),
1975 throw(cql_error(could_not_merge_sources, Message)).
1976
1977type_mismatch(type_mismatch(Link, Type1, Type2), type_mismatch(Link, Type1, Type2), Type1, Type2):-
1978 1979 1980 flag(sql_error, Link, Link+1),
1981 !.
1982
1984type_mismatch(_, _, _, _):- !.
1985
1988
1989
1990semantic_error(Error, Error, Level):-
1991 1992 1993 1994 !,
1995 format_sql_error(Error, _, Message),
1996 sql_gripe(Level, Message, []).
1997
1998semantic_error(_, _, _)