@@ -332,11 +332,11 @@ defmodule Ecto.Adapters.SQLite3.Connection do
332
332
end
333
333
end
334
334
335
- defp build_explain_query ( query , :query_plan ) do
335
+ def build_explain_query ( query , :query_plan ) do
336
336
IO . iodata_to_binary ( [ "EXPLAIN QUERY PLAN " , query ] )
337
337
end
338
338
339
- defp build_explain_query ( query , :instructions ) do
339
+ def build_explain_query ( query , :instructions ) do
340
340
IO . iodata_to_binary ( [ "EXPLAIN " , query ] )
341
341
end
342
342
@@ -444,6 +444,141 @@ defmodule Ecto.Adapters.SQLite3.Connection do
444
444
end )
445
445
end
446
446
447
+ @ impl true
448
+ def execute_ddl ( { _ , % Index { concurrently: true } } ) do
449
+ raise ArgumentError , "`concurrently` is not supported with SQLite3"
450
+ end
451
+
452
+ @ impl true
453
+ def execute_ddl ( { _ , % Index { only: true } } ) do
454
+ raise ArgumentError , "`only` is not supported with SQLite3"
455
+ end
456
+
457
+ @ impl true
458
+ def execute_ddl ( { _ , % Index { include: x } } ) when length ( x ) != 0 do
459
+ raise ArgumentError , "`include` is not supported with SQLite3"
460
+ end
461
+
462
+ @ impl true
463
+ def execute_ddl ( { _ , % Index { using: x } } ) when not is_nil ( x ) do
464
+ raise ArgumentError , "`using` is not supported with SQLite3"
465
+ end
466
+
467
+ @ impl true
468
+ def execute_ddl ( { _ , % Index { nulls_distinct: x } } ) when not is_nil ( x ) do
469
+ raise ArgumentError , "`nulls_distinct` is not supported with SQLite3"
470
+ end
471
+
472
+ @ impl true
473
+ def execute_ddl ( { :create , % Index { } = index } ) do
474
+ fields = intersperse_map ( index . columns , ", " , & index_expr / 1 )
475
+
476
+ [
477
+ [
478
+ "CREATE " ,
479
+ if_do ( index . unique , "UNIQUE " ) ,
480
+ "INDEX " ,
481
+ quote_name ( index . name ) ,
482
+ " ON " ,
483
+ quote_table ( index . prefix , index . table ) ,
484
+ " (" ,
485
+ fields ,
486
+ ?) ,
487
+ if_do ( index . where , [ " WHERE " , to_string ( index . where ) ] )
488
+ ]
489
+ ]
490
+ end
491
+
492
+ @ impl true
493
+ def execute_ddl ( { :create_if_not_exists , % Index { } = index } ) do
494
+ fields = intersperse_map ( index . columns , ", " , & index_expr / 1 )
495
+
496
+ [
497
+ [
498
+ "CREATE " ,
499
+ if_do ( index . unique , "UNIQUE " ) ,
500
+ "INDEX IF NOT EXISTS " ,
501
+ quote_name ( index . name ) ,
502
+ " ON " ,
503
+ quote_table ( index . prefix , index . table ) ,
504
+ " (" ,
505
+ fields ,
506
+ ?) ,
507
+ if_do ( index . where , [ " WHERE " , to_string ( index . where ) ] )
508
+ ]
509
+ ]
510
+ end
511
+
512
+ @ impl true
513
+ def execute_ddl ( { :drop , % Index { } = index } ) do
514
+ [
515
+ [
516
+ "DROP INDEX " ,
517
+ quote_table ( index . prefix , index . name )
518
+ ]
519
+ ]
520
+ end
521
+
522
+ @ impl true
523
+ def execute_ddl ( { :drop , % Index { } = index , _mode } ) do
524
+ execute_ddl ( { :drop , index } )
525
+ end
526
+
527
+ @ impl true
528
+ def execute_ddl ( { :drop_if_exists , % Index { concurrently: true } } ) do
529
+ raise ArgumentError , "`concurrently` is not supported with SQLite3"
530
+ end
531
+
532
+ @ impl true
533
+ def execute_ddl ( { :drop_if_exists , % Index { } = index } ) do
534
+ [
535
+ [
536
+ "DROP INDEX IF EXISTS " ,
537
+ quote_table ( index . prefix , index . name )
538
+ ]
539
+ ]
540
+ end
541
+
542
+ @ impl true
543
+ def execute_ddl ( { :drop_if_exists , % Index { } = index , _mode } ) do
544
+ execute_ddl ( { :drop_if_exists , index } )
545
+ end
546
+
547
+ @ impl true
548
+ def execute_ddl ( { :rename , % Table { } = current_table , % Table { } = new_table } ) do
549
+ [
550
+ [
551
+ "ALTER TABLE " ,
552
+ quote_table ( current_table . prefix , current_table . name ) ,
553
+ " RENAME TO " ,
554
+ quote_table ( nil , new_table . name )
555
+ ]
556
+ ]
557
+ end
558
+
559
+ @ impl true
560
+ def execute_ddl ( { :rename , % Table { } = current_table , old_col , new_col } ) do
561
+ [
562
+ [
563
+ "ALTER TABLE " ,
564
+ quote_table ( current_table . prefix , current_table . name ) ,
565
+ " RENAME COLUMN " ,
566
+ quote_name ( old_col ) ,
567
+ " TO " ,
568
+ quote_name ( new_col )
569
+ ]
570
+ ]
571
+ end
572
+
573
+ @ impl true
574
+ def execute_ddl ( string ) when is_binary ( string ) , do: [ string ]
575
+
576
+ @ impl true
577
+ def execute_ddl ( keyword ) when is_list ( keyword ) do
578
+ raise ArgumentError , "SQLite3 adapter does not support keyword lists in execute"
579
+ end
580
+
581
+ @ impl true
447
582
def execute_ddl ( { :create , % Index { } = index } ) do
448
583
fields = intersperse_map ( index . columns , ", " , & index_expr / 1 )
449
584
@@ -685,12 +820,11 @@ defmodule Ecto.Adapters.SQLite3.Connection do
685
820
686
821
def handle_call ( fun , _arity ) , do: { :fun , Atom . to_string ( fun ) }
687
822
688
- def distinct ( nil , _sources , _query ) , do: [ ]
689
- def distinct ( % QueryExpr { expr: true } , _sources , _query ) , do: "DISTINCT "
690
- def distinct ( % QueryExpr { expr: false } , _sources , _query ) , do: [ ]
823
+ defp distinct ( nil , _sources , _query ) , do: [ ]
824
+ defp distinct ( % QueryExpr { expr: true } , _sources , _query ) , do: "DISTINCT "
825
+ defp distinct ( % QueryExpr { expr: false } , _sources , _query ) , do: [ ]
691
826
692
- def distinct ( % QueryExpr { expr: expression } , _sources , query )
693
- when is_list ( expression ) do
827
+ defp distinct ( % QueryExpr { expr: exprs } , _sources , query ) when is_list ( exprs ) do
694
828
raise Ecto.QueryError ,
695
829
query: query ,
696
830
message: "DISTINCT with multiple columns is not supported by SQLite3"
@@ -809,6 +943,18 @@ defmodule Ecto.Adapters.SQLite3.Connection do
809
943
]
810
944
end
811
945
946
+ defp update_op ( :push , _quoted_key , _value , _sources , query ) do
947
+ raise Ecto.QueryError ,
948
+ query: query ,
949
+ message: "Arrays are not supported for SQLite3"
950
+ end
951
+
952
+ defp update_op ( :pull , _quoted_key , _value , _sources , query ) do
953
+ raise Ecto.QueryError ,
954
+ query: query ,
955
+ message: "Arrays are not supported for SQLite3"
956
+ end
957
+
812
958
defp update_op ( command , _quoted_key , _value , _sources , query ) do
813
959
raise Ecto.QueryError ,
814
960
query: query ,
@@ -823,15 +969,6 @@ defmodule Ecto.Adapters.SQLite3.Connection do
823
969
% JoinExpr { qual: _qual , ix: ix , source: source } ->
824
970
{ join , name } = get_source ( query , sources , ix , source )
825
971
[ join , " AS " | name ]
826
-
827
- # This is hold over from sqlite_ecto2. According to sqlite3
828
- # documentation, all of the join types are allowed.
829
- #
830
- # %JoinExpr{qual: qual} ->
831
- # raise Ecto.QueryError,
832
- # query: query,
833
- # message:
834
- # "SQLite3 adapter supports only inner joins on #{kind}, got: `#{qual}`"
835
972
end )
836
973
837
974
wheres =
@@ -853,14 +990,19 @@ defmodule Ecto.Adapters.SQLite3.Connection do
853
990
source: source ,
854
991
hints: hints
855
992
} ->
993
+ if hints != [ ] do
994
+ raise Ecto.QueryError ,
995
+ query: query ,
996
+ message: "join hints are not supported by SQLite3"
997
+ end
998
+
856
999
{ join , name } = get_source ( query , sources , ix , source )
857
1000
858
1001
[
859
1002
join_qual ( qual , query ) ,
860
1003
join ,
861
1004
" AS " ,
862
1005
name ,
863
- Enum . map ( hints , & [ ?\s | & 1 ] ) ,
864
1006
join_on ( qual , expression , sources , query )
865
1007
]
866
1008
end )
@@ -932,11 +1074,11 @@ defmodule Ecto.Adapters.SQLite3.Connection do
932
1074
def order_by ( % { order_bys: [ ] } , _sources ) , do: [ ]
933
1075
934
1076
def order_by ( % { order_bys: order_bys } = query , sources ) do
1077
+ order_bys = Enum . flat_map ( order_bys , & & 1 . expr )
1078
+
935
1079
[
936
1080
" ORDER BY "
937
- | intersperse_map ( order_bys , ", " , fn % QueryExpr { expr: expression } ->
938
- intersperse_map ( expression , ", " , & order_by_expr ( & 1 , sources , query ) )
939
- end )
1081
+ | intersperse_map ( order_bys , ", " , & order_by_expr ( & 1 , sources , query ) )
940
1082
]
941
1083
end
942
1084
@@ -1089,6 +1231,10 @@ defmodule Ecto.Adapters.SQLite3.Connection do
1089
1231
source
1090
1232
end
1091
1233
1234
+ def expr ( { :in , _ , [ _left , "[]" ] } , _sources , _query ) do
1235
+ "0"
1236
+ end
1237
+
1092
1238
def expr ( { :in , _ , [ _left , [ ] ] } , _sources , _query ) do
1093
1239
"0"
1094
1240
end
@@ -1111,6 +1257,7 @@ defmodule Ecto.Adapters.SQLite3.Connection do
1111
1257
[ expr ( left , sources , query ) , " IN " , expr ( subquery , sources , query ) ]
1112
1258
end
1113
1259
1260
+ # Super Hack to handle arrays in json
1114
1261
def expr ( { :in , _ , [ left , right ] } , sources , query ) do
1115
1262
[
1116
1263
expr ( left , sources , query ) ,
@@ -1227,8 +1374,13 @@ defmodule Ecto.Adapters.SQLite3.Connection do
1227
1374
def expr ( { fun , _ , args } , sources , query ) when is_atom ( fun ) and is_list ( args ) do
1228
1375
{ modifier , args } =
1229
1376
case args do
1230
- [ rest , :distinct ] -> { "DISTINCT " , [ rest ] }
1231
- _ -> { [ ] , args }
1377
+ [ _rest , :distinct ] ->
1378
+ raise Ecto.QueryError ,
1379
+ query: query ,
1380
+ message: "Distinct not supported in expressions"
1381
+
1382
+ _ ->
1383
+ { [ ] , args }
1232
1384
end
1233
1385
1234
1386
case handle_call ( fun , length ( args ) ) do
@@ -1245,7 +1397,7 @@ defmodule Ecto.Adapters.SQLite3.Connection do
1245
1397
def expr ( list , _sources , query ) when is_list ( list ) do
1246
1398
raise Ecto.QueryError ,
1247
1399
query: query ,
1248
- message: "Array type is not supported by SQLite3"
1400
+ message: "Array literals are not supported by SQLite3"
1249
1401
end
1250
1402
1251
1403
def expr ( % Decimal { } = decimal , _sources , _query ) do
@@ -1260,7 +1412,7 @@ defmodule Ecto.Adapters.SQLite3.Connection do
1260
1412
1261
1413
def expr ( % Ecto.Query.Tagged { value: other , type: type } , sources , query )
1262
1414
when type in [ :decimal , :float ] do
1263
- [ "(" , expr ( other , sources , query ) , " + 0 )" ]
1415
+ [ "CAST (" , expr ( other , sources , query ) , " AS REAL )" ]
1264
1416
end
1265
1417
1266
1418
def expr ( % Ecto.Query.Tagged { value: other , type: type } , sources , query ) do
@@ -1608,7 +1760,7 @@ defmodule Ecto.Adapters.SQLite3.Connection do
1608
1760
end )
1609
1761
1610
1762
if length ( pks ) > 1 do
1611
- composite_pk_expr = pks |> Enum . reverse ( ) |> Enum . map_join ( ", " , & quote_name / 1 )
1763
+ composite_pk_expr = pks |> Enum . reverse ( ) |> Enum . map_join ( "," , & quote_name / 1 )
1612
1764
1613
1765
{
1614
1766
% { table | primary_key: :composite } ,
0 commit comments