Pair your devices with a code and playback position follows you: pause on this device, hit resume on the other. Position is saved to the site every minute and on pause.
Open this panel on your other device and enter the same code.
Starts this lesson and continues through 0 more to the end of the course.
Redshift descends from PostgreSQL, uses a PostgreSQL wire protocol, and accepts a great deal of PostgreSQL syntax. Which is exactly why people get hurt by it.
AWS puts the warning in bold at the top of the page:
"Important. Do not assume that the semantics of elements that Amazon Redshift and PostgreSQL have in common are identical. Make sure to consult the Amazon Redshift Developer Guide SQL commands to understand the often subtle differences." — Unsupported PostgreSQL features (verified 2026-08-12)
"Often subtle differences" is doing a lot of work in that sentence. This lesson is about the ones that change results, not the ones that change syntax — because a syntax difference throws an error and a semantic difference ships to production.
This is the single most important thing in this lesson, and it is a favourite senior interview question.
The unsupported list includes constraints — unique, foreign key, primary key, check, exclusion. And then:
"Unique, primary key, and foreign key constraints are permitted, but they are informational only. They are not enforced by the system, but they are used by the query planner."
Read that twice. Three facts, and the third is the dangerous one:
CREATE TABLE succeeds.⚠️ Consequence: declaring a primary key that isn't actually unique can produce wrong results, not just slow ones. If the planner is told a column is unique, it may legitimately eliminate a de-duplication step or simplify a join, because you promised there were no duplicates. If there are duplicates, the optimisation is still valid given the promise — the promise was false.
This is a genuinely different failure mode from anything in PostgreSQL, where the constraint would have rejected the duplicate insert at write time.
What to do about it:
-- This must return zero rows. Run it as a pipeline step, not as a manual habit.
SELECT customer_id, COUNT(*) AS n
FROM dim_customer
GROUP BY customer_id
HAVING COUNT(*) > 1;
If an interviewer asks "does Redshift enforce primary keys?", the complete answer is: no — but the planner trusts them, so a false declaration can change your results, not just your performance. That last clause is what distinguishes a strong answer.
Verbatim from the same page, the features Redshift does not support:
| Not supported | Practical impact |
|---|---|
| Table partitioning (range and list) | You partition through distribution and sort keys instead — module RS1 |
| Indexes | There are none. Sort keys and zone maps do this job |
| Tablespaces | — |
| Constraints (enforcement) | See above |
| Inheritance | — |
| NULLS clause in window functions | ORDER BY x DESC NULLS LAST unavailable in OVER (...) — lesson 4 |
| Collations | "does not support locale-specific or user-defined collation sequences" |
| Value expressions: subscripted expressions, array constructors, row constructors | Rewrites needed for array-ish code |
| Triggers | Do it in the pipeline |
| Table functions | — |
| VALUES list used as constant tables | SELECT * FROM (VALUES ...) t(a,b) won't work — build a CTE or temp table |
| Sequences | No nextval(). Use IDENTITY — verify semantics before relying on gap-free numbering |
| Full text search | — |
| SQL/MED (management of external data) | — |
psql |
"The Amazon Redshift RSQL client is supported" |
System columns oid, xmin, ctid, etc. |
Not defined, and reserved — cannot be used as user column names |
The two I'd flag hardest for day-to-day work are the NULLS clause (because it silently changes
which row wins in a dedup) and the VALUES list (because it breaks the most natural way to write
a small lookup inline, and the failure is at least loud).
New arrivals from PostgreSQL reliably ask where the indexes are. There aren't any, and that isn't a gap.
Redshift is a columnar, distributed, analytic store. Instead of B-tree indexes it uses:
That's the model, and it's a different set of decisions from indexing. Module RS1 covers choosing them. The relevant point here: do not try to reproduce OLTP index thinking in Redshift. The lever is data layout, not auxiliary structures.
The page carries a banner:
"Amazon Redshift will no longer support the use of Python UDFs after June 30, 2026. We will start enforcing it in phases." — read 2026-08-12
That date is in the past. Enforcement is in progress now, in phases. If you have Python UDFs in Redshift:
This is exactly the class of change that a static training course gets wrong, which is why every lesson here carries a verification date.
If your platform is Redshift plus Athena/Trino plus Spark SQL — a very common AWS shape, and the one underneath this course's QuickSight track — you are writing in three dialects that agree on most syntax and disagree in the corners.
A working discipline:
QUALIFY doesn't.NULL ordering and
type coercion are the usual culprits.⚠️ I have deliberately not listed Athena/Trino and Spark SQL divergences here, because I did not fetch their documentation for this lesson and I am not going to reconstruct them from memory. Module DL0 covers Athena and PS0 covers Spark SQL, each against their own sources.
ORDER BY updated_at DESC NULLS LAST inside a window in Redshift. What now?NULLS clause in window functions is on the unsupported list.
Control null ordering explicitly instead, e.g. by ordering on a coalesced expression or adding a
leading term that sorts nulls where you want them. Verify the exact form on your cluster.HAVING COUNT(*) > 1 check on two of them live.