Skip to content

Commit cb910f0

Browse files
committed
Updates
1 parent 0f20469 commit cb910f0

34 files changed

+2248
-46
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.class
33
.vagrant/
44

5+
/dist/
56
# haskell compile artefacts
67
*.o
78
*.hi

Rakefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
require 'rake'
2+
require 'pry'
3+
4+
markdowns = Rake::FileList.new('**/*.md') do |fl|
5+
fl.exclude do |f|
6+
`git ls-files #{f}`.empty?
7+
end
8+
end
9+
10+
# all foo/bar/blah.md becomes foo/bar/blah.html
11+
htmls = markdowns.ext('html').pathmap('dist/%p')
12+
13+
task default: :html
14+
15+
task html: htmls
16+
17+
# tell rake to create the dist dir if it does not exist
18+
# also creates a "directory task"
19+
directory 'dist'
20+
21+
# tell rake how to convert a markdown file to html
22+
rule '.html' => ['.md', 'dist'] do |t| # t is instance of Rake::Task
23+
# puts "mkdir -p #{t.name.pathmap('%d')}"
24+
# puts "pandoc -o #{t.name} #{t.source}"
25+
mkdir_p t.name.pathmap('%d')
26+
sh "pandoc -o dist/#{t.name} #{t.source}"
27+
end
28+
29+
task :clean do
30+
rm_rf 'dist'
31+
end

c/enums.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
enum printFormat
3+
{
4+
PRINT_NOTHING = 0, /* to make sure someone initializes this */
5+
PRINT_UNALIGNED,
6+
PRINT_ALIGNED,
7+
PRINT_WRAPPED,
8+
PRINT_HTML,
9+
PRINT_ASCIIDOC,
10+
PRINT_LATEX,
11+
PRINT_LATEX_LONGTABLE,
12+
PRINT_TROFF_MS
13+
/* add your favourite output format here ... */
14+
};
15+
16+
int
17+
main()
18+
{
19+
return PRINT_UNALIGNED;
20+
}

c/enums.s

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.section __TEXT,__text,regular,pure_instructions
2+
.macosx_version_min 10, 11
3+
.globl _main
4+
.align 4, 0x90
5+
_main: ## @main
6+
.cfi_startproc
7+
## BB#0:
8+
pushq %rbp
9+
Ltmp0:
10+
.cfi_def_cfa_offset 16
11+
Ltmp1:
12+
.cfi_offset %rbp, -16
13+
movq %rsp, %rbp
14+
Ltmp2:
15+
.cfi_def_cfa_register %rbp
16+
movl $3, %eax
17+
movl $0, -4(%rbp)
18+
popq %rbp
19+
retq
20+
.cfi_endproc
21+
22+
23+
.subsections_via_symbols

databases/book-learning-sql.md

Lines changed: 171 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* a "surrogate key" is a primary key containing columns inserted just to
2525
have a unique key e.g. an "id" column
2626
* a "compound key" is a key containing more than one column
27-
* a "foreign key" is one or more columns which can be used togother to
27+
* a "foreign key" is one or more columns which can be used together to
2828
uniquely idenify a single row in another table
2929
* whose only function as a way of linking this record to a record in
3030
another table
@@ -124,24 +124,189 @@ will warn you when it does that.
124124

125125
# Aside: Character sets and collations
126126

127-
QUESTION: is the lenght restriction on string types in bytes and if so how are
128-
multi-byte chars handled
129-
130127
* default character set is `latin1`
131128
* you can specify character set at the server, database table or column level
132129
* MySQL lets you mix and match character sets and encodings at all levels
133130

134-
See separate file on character sets, encodings, unicode etc.
131+
See my other notes on character sets, encodings, unicode etc.
135132

136133
```sql
137134
SHOW CHARACTER SET;
138135
-- look at the `maxlen` column to see how many bytes required by each character
139136
set
140137
```
141138

142-
END CHAP 2
139+
# Chapter 3: Queries
140+
141+
When query is sent f
142+
143+
1. client (lib or tool) makes connection to server
144+
1. client sends query text
145+
1. query is checked
146+
* syntax correct
147+
* user has permission to access data
148+
* user has permission to execute the query (functions etc.)
149+
1. query is handed to the optimizer to create an "execution plan"
150+
1. server executes the execution plan
151+
1. server returns table of results to client
152+
153+
## Query clauses
154+
155+
Queries are made up of 6 clauses
156+
157+
### 1. Select
158+
159+
```
160+
http://www.postgresqltutorial.com/postgresql-select-distinct/
161+
```
162+
163+
* first clause in the syntax but almost the last clause to be evaluated
164+
* filters columns from the big "in memory table" that From clause will build
165+
* things included as a column in the results are
166+
* column names from table created by Join clause
167+
* literals: number, string etc. `"foo"`, `33`
168+
* expressions: `some_col * 3`
169+
* built-in function calls
170+
* user defined function calls
171+
* allows you to define "column aliases" via 2 ways (AS is optional)
172+
1. `some_val result`
173+
1. `some_val AS result`
174+
* has two forms (three in postgres)
175+
1. `SELECT ALL ...`
176+
* ALL (the default) will return all candidate rows, including duplicates.
177+
1. `SELECT DISTINCT <column list> ...`
178+
* DISTINCT eliminates duplicate rows from the result. (one row is kept
179+
from each group of duplicates)
180+
* If you specify multiple columns, the DISTINCT clause will evaluate
181+
the duplicate based on the combination of values of those columns.
182+
* note that the 'DISTINCT` does not apply to a single column
183+
1. `SELECT DISTINCT ON (<expression>) <column list> FROM ...`
184+
* DISTINCT ON calcluates the result of `<expression>` for all rows and eliminates all but the first row for each group where the result is the same
185+
186+
Gotchas
187+
188+
* `SELECT DISTINCT` without an `ORDER BY` clause is a code smell!
189+
* the "first row" of each set is unpredictable unless ORDER BY is used to
190+
ensure that the desired row appears first.
191+
* Notice that the DISTINCT ON expression must match the leftmost expression in
192+
the ORDER BY clause.
193+
194+
```sql
195+
-- * these functions are defined in SQL (alternatives: pgsql, C, python, ruby etc.)
196+
-- * functions persist longer than just each query so we have to drop them each time we run this script
197+
drop function IF EXISTS one();
198+
CREATE FUNCTION one() RETURNS integer AS $$
199+
SELECT 1 AS result;
200+
$$ LANGUAGE SQL;
201+
202+
drop function IF EXISTS add_em(INTEGER, INTEGER);
203+
CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$
204+
SELECT $1 + $2;
205+
$$ LANGUAGE SQL;
206+
207+
SELECT id,
208+
bt_transaction_id,
209+
'hello' AS literal_string,
210+
'other' no_as_literal_string,
211+
33 AS literal_int,
212+
4 * 5 AS expression,
213+
one() AS user_defined_func,
214+
add_em(4,6) AS user_defined_func_2,
215+
round(3.1459) AS built_in_func
216+
FROM settled_transactions;
217+
```
218+
219+
220+
### 2. From
221+
222+
* identifies tables to pull data from and how they should be joined into a single table
223+
* types of table
224+
1. permenant table
225+
* stored on disk
226+
2. temporary table
227+
* created as teh result of a subquery
228+
* `SELECT a.foo, b.foo FROM (SELECT ... FROM ... WHERE ...) AS a;`
229+
3. virtual table
230+
* views
231+
232+
Subqueries
233+
234+
* a query embedded in another query
235+
* returns a table that can be used by the outer query
236+
* it is very common to alias the returned table so it can easily be used by the
237+
outer query
238+
* covered more in chap 9
239+
240+
Syntax is:
241+
242+
```sql
243+
SELECT ... FROM (subquery) AS subq_result WHERE ...
244+
SELECT a.foo, b.foo FROM (SELECT ... FROM ... WHERE ...) AS a;
245+
```
246+
247+
View
248+
249+
* a query which is stored in the "data dictionary"
250+
* its data is not stored on disk
251+
252+
```sql
253+
CREATE VIEW <view_name> AS <select statement>
254+
CREATE VIEW some_view AS SELECT a, b, c FROM ...
255+
```
256+
257+
Joins
258+
259+
* specify how to combine the given permenant, virtual, temporary tables into
260+
one large table
261+
* it is very common to alias tables uses in a join
262+
263+
```sql
264+
SELECT <things> FROM <table-a> AS a <join condition> <table-b> AS b ON <on-condition>
265+
-- again the AS keyword is optional
266+
```
267+
268+
UP TO START WHERE CLAUSE
269+
### 3. Where
270+
271+
* filters unwanted rows from the big "in memory table" or "result set table"
272+
that From will build.
273+
* WHERE takes one or more "filter conditions"
274+
* each filter condition is combined using a logical AND, OR, NOT.
275+
* note that `=` is the equality symbol in a filter condition (not `==` as it is in most programming languages)
276+
```
277+
WHERE <filter-condition> and|or|not <filter-condition> ...
278+
```
279+
280+
### 4. Order by
281+
282+
* sort the rows of the final result set by one or more columns
283+
284+
285+
### 5. Group by
286+
287+
* finds trends in data
288+
* groups rows together by common column values
289+
* HAVING filters grouped data the same way WHERE filters raw data
290+
* described more fully in chap 8
291+
* each row in the result table that GROUP BY creates is a "group"!
292+
* GROUP BY is all about collapsing multiple rows in the results table - it does not change columns.
293+
* To collapse multiple rows into a single row we need to instruct the DB about how to do it for each column
294+
* some columns will have the same value for each row so the output value can just be the input
295+
* this is the case for the columns you specify in the GROUP BY clause (because we have chosen to use these columns to make our categories)
296+
* other columns will need a function to help with a signature a bit like
297+
* `function boil_down(column_values: Set<T>) -> <T>`
298+
* examples of "boil down" functions are
299+
* sum()
300+
* max()
301+
* min()
302+
303+
### 6. Having
304+
305+
* filters out unwanted groups
306+
* HAVING filters grouped data the same way WHERE filters raw data
143307

144308

309+
UP TO END OF SELECT CLAUSE IN CHAP 3
145310

146311

147312

databases/window-functions.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Window functions
2+
3+
```
4+
SELECT a, b, avg(c) OVER (PARTITION BY a) FROM some_table;
5+
SELECT <col-1>, <col-2>, <window-function-col> FROM <source-table>
6+
<window-function-col> is <grouping-func> OVER (PARTITION BY <partition-col-name>)
7+
```
8+
9+
How postgres generates the `<result-table>`
10+
11+
* foreach row in `<source-table>`
12+
* start building new resulttable row
13+
* copy `<col-1>` and `<col-2>` from `<source-table>` to `<result-table>`
14+
* start processing the <window-function-col>
15+
1. read the value of <partition-col-name> from the current row
16+
2. use that value to do a search of the table for all rows whose
17+
<partition-col-name> matches that value.
18+
3. take the set of rows (note: full rows of table) generated in the
19+
step above and feed it into the `<grouping-func>`.
20+
4. copy the output of the gropuing function into the result-table row
21+
22+

elixir/anonymous-functions.exs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ IO.puts handle_open.(File.open("./notthere.txt"))
3030
# return “FizzBuzz.” If the first is zero, return “Fizz.” If the second is
3131
# zero, return “Buzz.” Otherwise return the third argument”
3232

33-
# note: no static types for args or return value!
33+
# note: no enforced types for args or return value!
3434
buzzer = fn
3535
0, 0, _ -> "FizzBuzz"
3636
0, _, _ -> "Fizz"
@@ -87,8 +87,10 @@ IO.puts apply.(add_two, 55)
8787
# & the "function capture" operator
8888
# =================================
8989

90+
# these are equivalent
9091
doubler_1 = fn x -> x * 2 end
9192
doubler_2 = &(&1 * 2)
93+
9294
# & operator
9395

9496
# Uses:
@@ -110,8 +112,10 @@ isp = &Kernel.inspect(&1)
110112
isp = &Kernel.inspect/1 # same as above
111113

112114
list = [1,3,5,7,9]
115+
113116
IO.puts Kernel.inspect(Enum.map(list, doubler_2))
114-
IO.puts isp.(Enum.map(list, doubler_2))
117+
IO.puts isp.(Enum.map(list, doubler_2)) # note it is invoked as anonymous func i.e. isp.(things)
118+
115119
IO.puts Kernel.inspect(Enum.map(list, &(&1 * 2))) # short syntax nice for quick inline functions
116120
IO.inspect Enum.map(list, &(&1 * 2)) # short syntax nice for quick inline functions
117121

@@ -121,7 +125,9 @@ Enum.each [1,2,3,4], fn x -> IO.inspect x end
121125
Enum.each [1,2,3,4], &IO.inspect/1
122126

123127

128+
# Blocks
129+
# ======
130+
124131
# blocks are used to create scopes in elixir
125132
# their syntax is do: (<STATEMENTS SEPARATED BY NEWLINES>)
126133
# but the do..end syntax is more common
127-

elixir/attributes.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ defmodule Foo do
1919
IO.puts "#{@author} at #{@version}"
2020
end
2121

22-
# you can redefine attributes - what is the use-case for this?
22+
# you can redefine attributes - a good example of this is using @doc to
23+
# document functions
2324
@author "Totoro"
2425
@version "blah"
2526

elixir/basic-types.exs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ header.("Strings")
2222
# Unicode codepoints.
2323
# * => Elixir strings are "UTF-8 encoded binaries"
2424
#
25-
# The "weird l" has code point 322 so cannot be represented as one byte
25+
# The "weird l" in the example below has code point 322 so cannot be
26+
# represented as one byte
2627
#
2728
# iex(1)> ex = "hełło"
2829
# "hełło"
@@ -51,8 +52,8 @@ IO.inspect String.length "foo"
5152
# Char lists
5253
# ##########
5354
#
54-
# * is a list of code point integers
55-
# * is delimited by single quotes
55+
# * delimited by single quotes
56+
# * a list of code point integers
5657
# * will display it as the glyphs not the codepoints as long as all the
5758
# codepoints are within the 0-255 range
5859
# * are useful when interfacing with Erlang (strings are lists in Erlang)

0 commit comments

Comments
 (0)